From 21f3d4806d2c50e4926bc2e3de8df6ea73eb4f3f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 5 Jun 2020 22:14:48 +1200 Subject: [PATCH 1/2] CVE-2020-10760 dsdb: Ensure a proper talloc tree for saved controls Otherwise a paged search on the GC port will fail as the ->data was not kept around for the second page of searches. An example command to produce this is bin/ldbsearch --paged -H ldap://$SERVER:3268 -U$USERNAME%$PASSWORD This shows up later in the partition module as: ERROR: AddressSanitizer: heap-use-after-free on address 0x60b00151ef20 at pc 0x7fec3f801aac bp 0x7ffe8472c270 sp 0x7ffe8472c260 READ of size 4 at 0x60b00151ef20 thread T0 (ldap(0)) #0 0x7fec3f801aab in talloc_chunk_from_ptr ../../lib/talloc/talloc.c:526 #1 0x7fec3f801aab in __talloc_get_name ../../lib/talloc/talloc.c:1559 #2 0x7fec3f801aab in talloc_check_name ../../lib/talloc/talloc.c:1582 #3 0x7fec1b86b2e1 in partition_search ../../source4/dsdb/samdb/ldb_modules/partition.c:780 or smb_panic_default: PANIC (pid 13287): Bad talloc magic value - unknown value (from source4/dsdb/samdb/ldb_modules/partition.c:780) BUG: https://bugzilla.samba.org/show_bug.cgi?id=14402 Signed-off-by: Andrew Bartlett --- source4/dsdb/samdb/ldb_modules/vlv_pagination.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source4/dsdb/samdb/ldb_modules/vlv_pagination.c b/source4/dsdb/samdb/ldb_modules/vlv_pagination.c index 99cff4ac642..908fc402521 100644 --- a/source4/dsdb/samdb/ldb_modules/vlv_pagination.c +++ b/source4/dsdb/samdb/ldb_modules/vlv_pagination.c @@ -746,6 +746,13 @@ vlv_copy_down_controls(TALLOC_CTX *mem_ctx, struct ldb_control **controls) continue; } new_controls[j] = talloc_steal(new_controls, control); + /* + * Sadly the caller is not obliged to make this a + * proper talloc tree, so we do so here. + */ + if (control->data) { + talloc_steal(control, control->data); + } j++; } new_controls[j] = NULL; -- 2.17.1 From 9ae8565a8a89689f46e5f081f1608effb769156a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 8 Jun 2020 16:32:14 +1200 Subject: [PATCH 2/2] CVE-2020-10760 dsdb: Add tests for paged_results and VLV over the Global Catalog port This should avoid a regression. (backported from master patch) [abartlet@samba.org: paged_search tests are not present in Samba 4.5] Signed-off-by: Andrew Bartlett --- source4/dsdb/tests/python/vlv.py | 57 +++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/source4/dsdb/tests/python/vlv.py b/source4/dsdb/tests/python/vlv.py index 7792845120a..cacf444296f 100644 --- a/source4/dsdb/tests/python/vlv.py +++ b/source4/dsdb/tests/python/vlv.py @@ -148,7 +148,7 @@ class VLVTests(samba.tests.TestCase): super(VLVTests, self).setUp() self.ldb = SamDB(host, credentials=creds, session_info=system_session(lp), lp=lp) - + self.ldb_ro = self.ldb self.base_dn = self.ldb.domain_dn() self.ou = "ou=vlv,%s" % self.base_dn if opts.delete_in_setup: @@ -190,6 +190,61 @@ class VLVTests(samba.tests.TestCase): if not opts.delete_in_setup: self.ldb.delete(self.ou, ['tree_delete:1']) + +class VLVTestsBase(TestsWithUserOU): + + # Run a vlv search and return important fields of the response control + def vlv_search(self, attr, expr, cookie="", after_count=0, offset=1): + sort_ctrl = "server_sort:1:0:%s" % attr + ctrl = "vlv:1:0:%d:%d:0" % (after_count, offset) + if cookie: + ctrl += ":" + cookie + + res = self.ldb_ro.search(self.ou, + expression=expr, + scope=ldb.SCOPE_ONELEVEL, + attrs=[attr], + controls=[ctrl, sort_ctrl]) + results = [str(x[attr][0]) for x in res] + + ctrls = [str(c) for c in res.controls if + str(c).startswith('vlv')] + self.assertEqual(len(ctrls), 1) + + spl = ctrls[0].rsplit(':') + cookie = "" + if len(spl) == 6: + cookie = spl[-1] + + return results, cookie + + +class VLVTestsRO(VLVTestsBase): + def test_vlv_simple_double_run(self): + """Do the simplest possible VLV query to confirm if VLV + works at all. Useful for showing VLV as a whole works + on Global Catalog (for example)""" + attr = 'roomNumber' + expr = "(objectclass=user)" + + # Start new search + full_results, cookie = self.vlv_search(attr, expr, + after_count=len(self.users)) + + results, cookie = self.vlv_search(attr, expr, cookie=cookie, + after_count=len(self.users)) + expected_results = full_results + self.assertEqual(results, expected_results) + + +class VLVTestsGC(VLVTestsRO): + def setUp(self): + super(VLVTestsRO, self).setUp() + self.ldb_ro = SamDB(host + ":3268", credentials=creds, + session_info=system_session(lp), lp=lp) + + +class VLVTests(VLVTestsBase): def get_full_list(self, attr, include_cn=False): """Fetch the whole list sorted on the attribute, using the VLV. This way you get a VLV cookie.""" -- 2.17.1