fix CVE-2020-10700 and CVE-2020-10704
This commit is contained in:
parent
b406be5258
commit
7cef557ed7
222
CVE-2020-10700-1.patch
Normal file
222
CVE-2020-10700-1.patch
Normal file
@ -0,0 +1,222 @@
|
||||
From 0e77fa7747d789bd8c9256373498a352251f6877 Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Bartlett <abartlet@samba.org>
|
||||
Date: Mon, 30 Mar 2020 09:44:20 +0000
|
||||
Subject: [PATCH 1/4] CVE-2020-10700: dsdb: Add test for ASQ and ASQ in
|
||||
combination with paged_results
|
||||
|
||||
Thanks to Andrei Popa <andrei.popa@next-gen.ro> for finding,
|
||||
reporting and working with us to diagnose this issue!
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14331
|
||||
|
||||
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
|
||||
Reviewed-by: Gary Lockyer <gary@catalyst.net.nz>
|
||||
---
|
||||
selftest/knownfail.d/asq | 1 +
|
||||
source4/dsdb/tests/python/asq.py | 171 +++++++++++++++++++++++++++++++
|
||||
source4/selftest/tests.py | 1 +
|
||||
3 files changed, 173 insertions(+)
|
||||
create mode 100644 selftest/knownfail.d/asq
|
||||
create mode 100644 source4/dsdb/tests/python/asq.py
|
||||
|
||||
diff --git a/selftest/knownfail.d/asq b/selftest/knownfail.d/asq
|
||||
new file mode 100644
|
||||
index 00000000000..eb0e3e0aba1
|
||||
--- /dev/null
|
||||
+++ b/selftest/knownfail.d/asq
|
||||
@@ -0,0 +1 @@
|
||||
+samba4.asq.python\(ad_dc_default\).__main__.ASQLDAPTest.test_asq_paged
|
||||
\ No newline at end of file
|
||||
diff --git a/source4/dsdb/tests/python/asq.py b/source4/dsdb/tests/python/asq.py
|
||||
new file mode 100644
|
||||
index 00000000000..a32c9f40cd3
|
||||
--- /dev/null
|
||||
+++ b/source4/dsdb/tests/python/asq.py
|
||||
@@ -0,0 +1,171 @@
|
||||
+#!/usr/bin/env python3
|
||||
+#
|
||||
+# Test ASQ LDAP control behaviour in Samba
|
||||
+# Copyright (C) Andrew Bartlett 2019-2020
|
||||
+#
|
||||
+# Based on Unit tests for the notification control
|
||||
+# Copyright (C) Stefan Metzmacher 2016
|
||||
+#
|
||||
+# This program is free software; you can redistribute it and/or modify
|
||||
+# it under the terms of the GNU General Public License as published by
|
||||
+# the Free Software Foundation; either version 3 of the License, or
|
||||
+# (at your option) any later version.
|
||||
+#
|
||||
+# This program is distributed in the hope that it will be useful,
|
||||
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+# GNU General Public License for more details.
|
||||
+#
|
||||
+# You should have received a copy of the GNU General Public License
|
||||
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
+
|
||||
+import optparse
|
||||
+import sys
|
||||
+import os
|
||||
+import random
|
||||
+
|
||||
+sys.path.insert(0, "bin/python")
|
||||
+import samba
|
||||
+from samba.tests.subunitrun import SubunitOptions, TestProgram
|
||||
+
|
||||
+import samba.getopt as options
|
||||
+
|
||||
+from samba.auth import system_session
|
||||
+from samba import ldb
|
||||
+from samba.samdb import SamDB
|
||||
+from samba.ndr import ndr_unpack
|
||||
+from samba import gensec
|
||||
+from samba.credentials import Credentials
|
||||
+import samba.tests
|
||||
+
|
||||
+from ldb import SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError
|
||||
+from ldb import ERR_TIME_LIMIT_EXCEEDED, ERR_ADMIN_LIMIT_EXCEEDED, ERR_UNWILLING_TO_PERFORM
|
||||
+from ldb import Message
|
||||
+
|
||||
+parser = optparse.OptionParser("large_ldap.py [options] <host>")
|
||||
+sambaopts = options.SambaOptions(parser)
|
||||
+parser.add_option_group(sambaopts)
|
||||
+parser.add_option_group(options.VersionOptions(parser))
|
||||
+# use command line creds if available
|
||||
+credopts = options.CredentialsOptions(parser)
|
||||
+parser.add_option_group(credopts)
|
||||
+subunitopts = SubunitOptions(parser)
|
||||
+parser.add_option_group(subunitopts)
|
||||
+opts, args = parser.parse_args()
|
||||
+
|
||||
+if len(args) < 1:
|
||||
+ parser.print_usage()
|
||||
+ sys.exit(1)
|
||||
+
|
||||
+url = args[0]
|
||||
+
|
||||
+lp = sambaopts.get_loadparm()
|
||||
+creds = credopts.get_credentials(lp)
|
||||
+
|
||||
+
|
||||
+class ASQLDAPTest(samba.tests.TestCase):
|
||||
+
|
||||
+ def setUp(self):
|
||||
+ super(ASQLDAPTest, self).setUp()
|
||||
+ self.ldb = samba.Ldb(url, credentials=creds, session_info=system_session(lp), lp=lp)
|
||||
+ self.base_dn = self.ldb.get_default_basedn()
|
||||
+ self.NAME_ASQ="asq_" + format(random.randint(0, 99999), "05")
|
||||
+ self.OU_NAME_ASQ= self.NAME_ASQ + "_ou"
|
||||
+ self.ou_dn = ldb.Dn(self.ldb, "ou=" + self.OU_NAME_ASQ + "," + str(self.base_dn))
|
||||
+
|
||||
+ samba.tests.delete_force(self.ldb, self.ou_dn,
|
||||
+ controls=['tree_delete:1'])
|
||||
+
|
||||
+ self.ldb.add({
|
||||
+ "dn": self.ou_dn,
|
||||
+ "objectclass": "organizationalUnit",
|
||||
+ "ou": self.OU_NAME_ASQ})
|
||||
+
|
||||
+ self.members = []
|
||||
+ self.members2 = []
|
||||
+
|
||||
+ for x in range(20):
|
||||
+ name = self.NAME_ASQ + "_" + str(x)
|
||||
+ dn = ldb.Dn(self.ldb,
|
||||
+ "cn=" + name + "," + str(self.ou_dn))
|
||||
+ self.members.append(dn)
|
||||
+ self.ldb.add({
|
||||
+ "dn": dn,
|
||||
+ "objectclass": "group"})
|
||||
+
|
||||
+ for x in range(20):
|
||||
+ name = self.NAME_ASQ + "_" + str(x + 20)
|
||||
+ dn = ldb.Dn(self.ldb,
|
||||
+ "cn=" + name + "," + str(self.ou_dn))
|
||||
+ self.members2.append(dn)
|
||||
+ self.ldb.add({
|
||||
+ "dn": dn,
|
||||
+ "objectclass": "group",
|
||||
+ "member": [str(x) for x in self.members]})
|
||||
+
|
||||
+ name = self.NAME_ASQ + "_" + str(x + 40)
|
||||
+ self.top_dn = ldb.Dn(self.ldb,
|
||||
+ "cn=" + name + "," + str(self.ou_dn))
|
||||
+ self.ldb.add({
|
||||
+ "dn": self.top_dn,
|
||||
+ "objectclass": "group",
|
||||
+ "member": [str(x) for x in self.members2]})
|
||||
+
|
||||
+ def tearDown(self):
|
||||
+ samba.tests.delete_force(self.ldb, self.ou_dn,
|
||||
+ controls=['tree_delete:1'])
|
||||
+
|
||||
+ def test_asq(self):
|
||||
+ """Testing ASQ behaviour.
|
||||
+
|
||||
+ ASQ is very strange, it turns a BASE search into a search for
|
||||
+ all the objects pointed to by the specified attribute,
|
||||
+ returning multiple entries!
|
||||
+
|
||||
+ """
|
||||
+
|
||||
+ msgs = self.ldb.search(base=self.top_dn,
|
||||
+ scope=ldb.SCOPE_BASE,
|
||||
+ attrs=["objectGUID", "cn", "member"],
|
||||
+ controls=["asq:1:member"])
|
||||
+
|
||||
+ self.assertEqual(len(msgs), 20)
|
||||
+
|
||||
+ for msg in msgs:
|
||||
+ self.assertNotEqual(msg.dn, self.top_dn)
|
||||
+ self.assertIn(msg.dn, self.members2)
|
||||
+ for group in msg["member"]:
|
||||
+ self.assertIn(ldb.Dn(self.ldb, str(group)),
|
||||
+ self.members)
|
||||
+
|
||||
+ def test_asq_paged(self):
|
||||
+ """Testing ASQ behaviour with paged_results set.
|
||||
+
|
||||
+ ASQ is very strange, it turns a BASE search into a search for
|
||||
+ all the objects pointed to by the specified attribute,
|
||||
+ returning multiple entries!
|
||||
+
|
||||
+ """
|
||||
+
|
||||
+ msgs = self.ldb.search(base=self.top_dn,
|
||||
+ scope=ldb.SCOPE_BASE,
|
||||
+ attrs=["objectGUID", "cn", "member"],
|
||||
+ controls=["asq:1:member",
|
||||
+ "paged_results:1:1024"])
|
||||
+
|
||||
+ self.assertEqual(len(msgs), 20)
|
||||
+
|
||||
+ for msg in msgs:
|
||||
+ self.assertNotEqual(msg.dn, self.top_dn)
|
||||
+ self.assertIn(msg.dn, self.members2)
|
||||
+ for group in msg["member"]:
|
||||
+ self.assertIn(ldb.Dn(self.ldb, str(group)),
|
||||
+ self.members)
|
||||
+
|
||||
+if "://" not in url:
|
||||
+ if os.path.isfile(url):
|
||||
+ url = "tdb://%s" % url
|
||||
+ else:
|
||||
+ url = "ldap://%s" % url
|
||||
+
|
||||
+TestProgram(module=__name__, opts=subunitopts)
|
||||
diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py
|
||||
index ae2b10ae659..52db18a872b 100755
|
||||
--- a/source4/selftest/tests.py
|
||||
+++ b/source4/selftest/tests.py
|
||||
@@ -885,6 +885,7 @@ plantestsuite_loadlist("samba4.tokengroups.krb5.python(ad_dc_default)", "ad_dc_d
|
||||
plantestsuite_loadlist("samba4.tokengroups.ntlm.python(ad_dc_default)", "ad_dc_default:local", [python, os.path.join(DSDB_PYTEST_DIR, "token_group.py"), '$SERVER', '-U"$USERNAME%$PASSWORD"', '--workgroup=$DOMAIN', '-k', 'no', '$LOADLIST', '$LISTOPT'])
|
||||
plantestsuite("samba4.sam.python(fl2008r2dc)", "fl2008r2dc", [python, os.path.join(DSDB_PYTEST_DIR, "sam.py"), '$SERVER', '-U"$USERNAME%$PASSWORD"', '--workgroup=$DOMAIN'])
|
||||
plantestsuite("samba4.sam.python(ad_dc_default)", "ad_dc_default", [python, os.path.join(DSDB_PYTEST_DIR, "sam.py"), '$SERVER', '-U"$USERNAME%$PASSWORD"', '--workgroup=$DOMAIN'])
|
||||
+plantestsuite("samba4.asq.python(ad_dc_default)", "ad_dc_default", [python, os.path.join(DSDB_PYTEST_DIR, "asq.py"), '$SERVER', '-U"$USERNAME%$PASSWORD"', '--workgroup=$DOMAIN'])
|
||||
plantestsuite("samba4.user_account_control.python(ad_dc_default)", "ad_dc_default", [python, os.path.join(DSDB_PYTEST_DIR, "user_account_control.py"), '$SERVER', '-U"$USERNAME%$PASSWORD"', '--workgroup=$DOMAIN'])
|
||||
|
||||
for env in ['ad_dc_default:local', 'schema_dc:local']:
|
||||
--
|
||||
2.17.1
|
||||
|
||||
|
||||
82
CVE-2020-10700-3.patch
Normal file
82
CVE-2020-10700-3.patch
Normal file
@ -0,0 +1,82 @@
|
||||
From 34f9e6e969913629f9241522020c5895dc9636dc Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Bartlett <abartlet@samba.org>
|
||||
Date: Wed, 11 Mar 2020 16:43:31 +1300
|
||||
Subject: [PATCH 3/4] CVE-2020-10700: dsdb: Do not permit the ASQ control for
|
||||
the GUID search in paged_results
|
||||
|
||||
ASQ is a very strange control and a BASE search can return multiple results
|
||||
that are NOT the requested DN, but the DNs pointed to by it!
|
||||
|
||||
Thanks to Andrei Popa <andrei.popa@next-gen.ro> for finding,
|
||||
reporting and working with us to diagnose this issue!
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14331
|
||||
|
||||
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
|
||||
Reviewed-by: Gary Lockyer <gary@catalyst.net.nz>
|
||||
---
|
||||
selftest/knownfail.d/asq | 1 -
|
||||
source4/dsdb/samdb/ldb_modules/paged_results.c | 18 +++++++++++++-----
|
||||
2 files changed, 13 insertions(+), 6 deletions(-)
|
||||
delete mode 100644 selftest/knownfail.d/asq
|
||||
|
||||
diff --git a/selftest/knownfail.d/asq b/selftest/knownfail.d/asq
|
||||
deleted file mode 100644
|
||||
index eb0e3e0aba1..00000000000
|
||||
--- a/selftest/knownfail.d/asq
|
||||
+++ /dev/null
|
||||
@@ -1 +0,0 @@
|
||||
-samba4.asq.python\(ad_dc_default\).__main__.ASQLDAPTest.test_asq_paged
|
||||
\ No newline at end of file
|
||||
diff --git a/source4/dsdb/samdb/ldb_modules/paged_results.c b/source4/dsdb/samdb/ldb_modules/paged_results.c
|
||||
index 940d2254fb0..dc211dd18ce 100644
|
||||
--- a/source4/dsdb/samdb/ldb_modules/paged_results.c
|
||||
+++ b/source4/dsdb/samdb/ldb_modules/paged_results.c
|
||||
@@ -483,8 +483,14 @@ paged_results_copy_down_controls(TALLOC_CTX *mem_ctx,
|
||||
if (control->oid == NULL) {
|
||||
continue;
|
||||
}
|
||||
- if (strncmp(control->oid, LDB_CONTROL_PAGED_RESULTS_OID,
|
||||
- sizeof(LDB_CONTROL_PAGED_RESULTS_OID)) == 0) {
|
||||
+ if (strcmp(control->oid, LDB_CONTROL_PAGED_RESULTS_OID) == 0) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ /*
|
||||
+ * ASQ changes everything, do not copy it down for the
|
||||
+ * per-GUID search
|
||||
+ */
|
||||
+ if (strcmp(control->oid, LDB_CONTROL_ASQ_OID) == 0) {
|
||||
continue;
|
||||
}
|
||||
new_controls[j] = talloc_steal(new_controls, control);
|
||||
@@ -534,21 +540,23 @@ static bool paged_controls_same(struct ldb_request *req,
|
||||
|
||||
num_non_null_req_controls = 0;
|
||||
for (i=0; req->controls[i] != NULL; i++) {
|
||||
- if (req->controls[i]->oid != NULL) {
|
||||
+ if (req->controls[i]->oid != NULL &&
|
||||
+ strcmp(req->controls[i]->oid,
|
||||
+ LDB_CONTROL_ASQ_OID) != 0) {
|
||||
num_non_null_req_controls++;
|
||||
}
|
||||
}
|
||||
|
||||
/* At this point we have the number of non-null entries for both
|
||||
* control lists and we know that:
|
||||
- * 1. down_controls does not contain the paged control
|
||||
+ * 1. down_controls does not contain the paged control or ASQ
|
||||
* (because paged_results_copy_down_controls excludes it)
|
||||
* 2. req->controls does contain the paged control
|
||||
* (because this function is only called if this is true)
|
||||
* 3. down_controls is a subset of non-null controls in req->controls
|
||||
* (checked above)
|
||||
* So to confirm that the two lists are identical except for the paged
|
||||
- * control, all we need to check is: */
|
||||
+ * control and possibly ASQ, all we need to check is: */
|
||||
if (num_non_null_req_controls == num_down_controls + 1) {
|
||||
return true;
|
||||
}
|
||||
--
|
||||
2.17.1
|
||||
|
||||
|
||||
547
CVE-2020-10704-1.patch
Normal file
547
CVE-2020-10704-1.patch
Normal file
@ -0,0 +1,547 @@
|
||||
From b01952c6fb15b92fff3ad1bf8f1cf579875e5483 Mon Sep 17 00:00:00 2001
|
||||
From: Gary Lockyer <gary@catalyst.net.nz>
|
||||
Date: Fri, 3 Apr 2020 12:18:03 +1300
|
||||
Subject: [PATCH 1/8] CVE-2020-10704: lib util asn1: Add ASN.1 max tree depth
|
||||
|
||||
Add maximum parse tree depth to the call to asn1_init, which will be
|
||||
used to limit the depth of the ASN.1 parse tree.
|
||||
|
||||
Credit to OSS-Fuzz
|
||||
|
||||
REF: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=20454
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14334
|
||||
|
||||
Signed-off-by: Gary Lockyer <gary@catalyst.net.nz>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
---
|
||||
auth/gensec/gensec_util.c | 2 +-
|
||||
lib/util/asn1.c | 17 +++++++++-
|
||||
lib/util/asn1.h | 9 +++++-
|
||||
lib/util/tests/asn1_tests.c | 2 +-
|
||||
libcli/auth/spnego_parse.c | 6 ++--
|
||||
libcli/cldap/cldap.c | 2 +-
|
||||
libcli/ldap/ldap_message.c | 2 +-
|
||||
source3/lib/tldap.c | 4 +--
|
||||
source3/lib/tldap_util.c | 4 +--
|
||||
source3/libsmb/clispnego.c | 4 +--
|
||||
source3/torture/torture.c | 2 +-
|
||||
source4/auth/gensec/gensec_krb5.c | 4 +--
|
||||
source4/ldap_server/ldap_server.c | 2 +-
|
||||
source4/libcli/ldap/ldap_client.c | 2 +-
|
||||
source4/libcli/ldap/ldap_controls.c | 48 ++++++++++++++---------------
|
||||
15 files changed, 66 insertions(+), 44 deletions(-)
|
||||
|
||||
diff --git a/auth/gensec/gensec_util.c b/auth/gensec/gensec_util.c
|
||||
index 20c9c2a1fbb..e185acc0c20 100644
|
||||
--- a/auth/gensec/gensec_util.c
|
||||
+++ b/auth/gensec/gensec_util.c
|
||||
@@ -76,7 +76,7 @@ NTSTATUS gensec_generate_session_info_pac(TALLOC_CTX *mem_ctx,
|
||||
static bool gensec_gssapi_check_oid(const DATA_BLOB *blob, const char *oid)
|
||||
{
|
||||
bool ret = false;
|
||||
- struct asn1_data *data = asn1_init(NULL);
|
||||
+ struct asn1_data *data = asn1_init(NULL, ASN1_MAX_TREE_DEPTH);
|
||||
|
||||
if (!data) return false;
|
||||
|
||||
diff --git a/lib/util/asn1.c b/lib/util/asn1.c
|
||||
index 51da5424956..ec6e674ce20 100644
|
||||
--- a/lib/util/asn1.c
|
||||
+++ b/lib/util/asn1.c
|
||||
@@ -36,15 +36,19 @@ struct asn1_data {
|
||||
off_t ofs;
|
||||
struct nesting *nesting;
|
||||
bool has_error;
|
||||
+ unsigned depth;
|
||||
+ unsigned max_depth;
|
||||
};
|
||||
|
||||
/* allocate an asn1 structure */
|
||||
-struct asn1_data *asn1_init(TALLOC_CTX *mem_ctx)
|
||||
+struct asn1_data *asn1_init(TALLOC_CTX *mem_ctx, unsigned max_depth)
|
||||
{
|
||||
struct asn1_data *ret = talloc_zero(mem_ctx, struct asn1_data);
|
||||
if (ret == NULL) {
|
||||
DEBUG(0,("asn1_init failed! out of memory\n"));
|
||||
+ return ret;
|
||||
}
|
||||
+ ret->max_depth = max_depth;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -480,6 +484,11 @@ bool asn1_check_BOOLEAN(struct asn1_data *data, bool v)
|
||||
/* load a struct asn1_data structure with a lump of data, ready to be parsed */
|
||||
bool asn1_load(struct asn1_data *data, DATA_BLOB blob)
|
||||
{
|
||||
+ /*
|
||||
+ * Save the maximum depth
|
||||
+ */
|
||||
+ unsigned max_depth = data->max_depth;
|
||||
+
|
||||
ZERO_STRUCTP(data);
|
||||
data->data = (uint8_t *)talloc_memdup(data, blob.data, blob.length);
|
||||
if (!data->data) {
|
||||
@@ -487,6 +496,7 @@ bool asn1_load(struct asn1_data *data, DATA_BLOB blob)
|
||||
return false;
|
||||
}
|
||||
data->length = blob.length;
|
||||
+ data->max_depth = max_depth;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1103,9 +1113,14 @@ bool asn1_extract_blob(struct asn1_data *asn1, TALLOC_CTX *mem_ctx,
|
||||
*/
|
||||
void asn1_load_nocopy(struct asn1_data *data, uint8_t *buf, size_t len)
|
||||
{
|
||||
+ /*
|
||||
+ * Save max_depth
|
||||
+ */
|
||||
+ unsigned max_depth = data->max_depth;
|
||||
ZERO_STRUCTP(data);
|
||||
data->data = buf;
|
||||
data->length = len;
|
||||
+ data->max_depth = max_depth;
|
||||
}
|
||||
|
||||
int asn1_peek_full_tag(DATA_BLOB blob, uint8_t tag, size_t *packet_size)
|
||||
diff --git a/lib/util/asn1.h b/lib/util/asn1.h
|
||||
index ddd69863574..fc365724e93 100644
|
||||
--- a/lib/util/asn1.h
|
||||
+++ b/lib/util/asn1.h
|
||||
@@ -45,7 +45,14 @@ typedef struct asn1_data ASN1_DATA;
|
||||
|
||||
#define ASN1_MAX_OIDS 20
|
||||
|
||||
-struct asn1_data *asn1_init(TALLOC_CTX *mem_ctx);
|
||||
+/*
|
||||
+ * The maximum permitted depth for an ASN.1 parse tree, the limit is chosen
|
||||
+ * to align with the value for windows. Note that this value will trigger
|
||||
+ * ASAN stack overflow errors.
|
||||
+ */
|
||||
+#define ASN1_MAX_TREE_DEPTH 512
|
||||
+
|
||||
+struct asn1_data *asn1_init(TALLOC_CTX *mem_ctx, unsigned max_depth);
|
||||
void asn1_free(struct asn1_data *data);
|
||||
bool asn1_has_error(const struct asn1_data *data);
|
||||
void asn1_set_error(struct asn1_data *data);
|
||||
diff --git a/lib/util/tests/asn1_tests.c b/lib/util/tests/asn1_tests.c
|
||||
index e4b386ad785..ab5262c4ffb 100644
|
||||
--- a/lib/util/tests/asn1_tests.c
|
||||
+++ b/lib/util/tests/asn1_tests.c
|
||||
@@ -330,7 +330,7 @@ static bool test_asn1_Integer(struct torture_context *tctx)
|
||||
DATA_BLOB blob;
|
||||
int val;
|
||||
|
||||
- data = asn1_init(mem_ctx);
|
||||
+ data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
|
||||
if (!data) {
|
||||
goto err;
|
||||
}
|
||||
diff --git a/libcli/auth/spnego_parse.c b/libcli/auth/spnego_parse.c
|
||||
index f538b44552c..f7f19b10778 100644
|
||||
--- a/libcli/auth/spnego_parse.c
|
||||
+++ b/libcli/auth/spnego_parse.c
|
||||
@@ -296,7 +296,7 @@ ssize_t spnego_read_data(TALLOC_CTX *mem_ctx, DATA_BLOB data, struct spnego_data
|
||||
return ret;
|
||||
}
|
||||
|
||||
- asn1 = asn1_init(mem_ctx);
|
||||
+ asn1 = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
|
||||
if (asn1 == NULL) {
|
||||
return -1;
|
||||
}
|
||||
@@ -339,7 +339,7 @@ ssize_t spnego_read_data(TALLOC_CTX *mem_ctx, DATA_BLOB data, struct spnego_data
|
||||
|
||||
ssize_t spnego_write_data(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, struct spnego_data *spnego)
|
||||
{
|
||||
- struct asn1_data *asn1 = asn1_init(mem_ctx);
|
||||
+ struct asn1_data *asn1 = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
|
||||
ssize_t ret = -1;
|
||||
|
||||
if (asn1 == NULL) {
|
||||
@@ -411,7 +411,7 @@ bool spnego_write_mech_types(TALLOC_CTX *mem_ctx,
|
||||
DATA_BLOB *blob)
|
||||
{
|
||||
bool ret = false;
|
||||
- struct asn1_data *asn1 = asn1_init(mem_ctx);
|
||||
+ struct asn1_data *asn1 = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
|
||||
|
||||
if (asn1 == NULL) {
|
||||
return false;
|
||||
diff --git a/libcli/cldap/cldap.c b/libcli/cldap/cldap.c
|
||||
index daba37a21d7..8fa9ce0b273 100644
|
||||
--- a/libcli/cldap/cldap.c
|
||||
+++ b/libcli/cldap/cldap.c
|
||||
@@ -229,7 +229,7 @@ static bool cldap_socket_recv_dgram(struct cldap_socket *c,
|
||||
goto error;
|
||||
}
|
||||
|
||||
- asn1 = asn1_init(in);
|
||||
+ asn1 = asn1_init(in, ASN1_MAX_TREE_DEPTH);
|
||||
if (!asn1) {
|
||||
goto nomem;
|
||||
}
|
||||
diff --git a/libcli/ldap/ldap_message.c b/libcli/ldap/ldap_message.c
|
||||
index f21598374a1..ba82bddeab1 100644
|
||||
--- a/libcli/ldap/ldap_message.c
|
||||
+++ b/libcli/ldap/ldap_message.c
|
||||
@@ -390,7 +390,7 @@ _PUBLIC_ bool ldap_encode(struct ldap_message *msg,
|
||||
const struct ldap_control_handler *control_handlers,
|
||||
DATA_BLOB *result, TALLOC_CTX *mem_ctx)
|
||||
{
|
||||
- struct asn1_data *data = asn1_init(mem_ctx);
|
||||
+ struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
|
||||
int i, j;
|
||||
|
||||
if (!data) return false;
|
||||
diff --git a/source3/lib/tldap.c b/source3/lib/tldap.c
|
||||
index d6c6e8859a6..bf5fc05d785 100644
|
||||
--- a/source3/lib/tldap.c
|
||||
+++ b/source3/lib/tldap.c
|
||||
@@ -632,7 +632,7 @@ static void tldap_msg_received(struct tevent_req *subreq)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
- data = asn1_init(talloc_tos());
|
||||
+ data = asn1_init(talloc_tos(), ASN1_MAX_TREE_DEPTH);
|
||||
if (data == NULL) {
|
||||
status = TLDAP_NO_MEMORY;
|
||||
goto fail;
|
||||
@@ -763,7 +763,7 @@ static struct tevent_req *tldap_req_create(TALLOC_CTX *mem_ctx,
|
||||
if (req == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
- state->out = asn1_init(state);
|
||||
+ state->out = asn1_init(state, ASN1_MAX_TREE_DEPTH);
|
||||
if (state->out == NULL) {
|
||||
goto err;
|
||||
}
|
||||
diff --git a/source3/lib/tldap_util.c b/source3/lib/tldap_util.c
|
||||
index 1b86962a32e..168932a8a96 100644
|
||||
--- a/source3/lib/tldap_util.c
|
||||
+++ b/source3/lib/tldap_util.c
|
||||
@@ -644,7 +644,7 @@ static struct tevent_req *tldap_ship_paged_search(
|
||||
struct tldap_control *pgctrl;
|
||||
struct asn1_data *asn1 = NULL;
|
||||
|
||||
- asn1 = asn1_init(state);
|
||||
+ asn1 = asn1_init(state, ASN1_MAX_TREE_DEPTH);
|
||||
if (asn1 == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -783,7 +783,7 @@ static void tldap_search_paged_done(struct tevent_req *subreq)
|
||||
|
||||
TALLOC_FREE(state->cookie.data);
|
||||
|
||||
- asn1 = asn1_init(talloc_tos());
|
||||
+ asn1 = asn1_init(talloc_tos(), ASN1_MAX_TREE_DEPTH);
|
||||
if (tevent_req_nomem(asn1, req)) {
|
||||
return;
|
||||
}
|
||||
diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c
|
||||
index 4a0fbcd73af..1608f6a9960 100644
|
||||
--- a/source3/libsmb/clispnego.c
|
||||
+++ b/source3/libsmb/clispnego.c
|
||||
@@ -50,7 +50,7 @@ bool spnego_parse_negTokenInit(TALLOC_CTX *ctx,
|
||||
*secblob = data_blob_null;
|
||||
}
|
||||
|
||||
- data = asn1_init(talloc_tos());
|
||||
+ data = asn1_init(talloc_tos(), ASN1_MAX_TREE_DEPTH);
|
||||
if (data == NULL) {
|
||||
return false;
|
||||
}
|
||||
@@ -171,7 +171,7 @@ DATA_BLOB spnego_gen_krb5_wrap(TALLOC_CTX *ctx, const DATA_BLOB ticket, const ui
|
||||
ASN1_DATA *data;
|
||||
DATA_BLOB ret = data_blob_null;
|
||||
|
||||
- data = asn1_init(talloc_tos());
|
||||
+ data = asn1_init(talloc_tos(), ASN1_MAX_TREE_DEPTH);
|
||||
if (data == NULL) {
|
||||
return data_blob_null;
|
||||
}
|
||||
diff --git a/source3/torture/torture.c b/source3/torture/torture.c
|
||||
index a795e61125f..c4b0a7bc4f9 100644
|
||||
--- a/source3/torture/torture.c
|
||||
+++ b/source3/torture/torture.c
|
||||
@@ -11370,7 +11370,7 @@ tldap_build_extended_control(enum tldap_extended_val val)
|
||||
ZERO_STRUCT(empty_control);
|
||||
|
||||
if (val != EXTENDED_NONE) {
|
||||
- data = asn1_init(talloc_tos());
|
||||
+ data = asn1_init(talloc_tos(), ASN1_MAX_TREE_DEPTH);
|
||||
|
||||
if (!data) {
|
||||
return NULL;
|
||||
diff --git a/source4/auth/gensec/gensec_krb5.c b/source4/auth/gensec/gensec_krb5.c
|
||||
index 0323da87d29..b735063656a 100644
|
||||
--- a/source4/auth/gensec/gensec_krb5.c
|
||||
+++ b/source4/auth/gensec/gensec_krb5.c
|
||||
@@ -444,7 +444,7 @@ static DATA_BLOB gensec_gssapi_gen_krb5_wrap(TALLOC_CTX *mem_ctx, const DATA_BLO
|
||||
struct asn1_data *data;
|
||||
DATA_BLOB ret = data_blob_null;
|
||||
|
||||
- data = asn1_init(mem_ctx);
|
||||
+ data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
|
||||
if (!data || !ticket->data) {
|
||||
return ret;
|
||||
}
|
||||
@@ -478,7 +478,7 @@ static DATA_BLOB gensec_gssapi_gen_krb5_wrap(TALLOC_CTX *mem_ctx, const DATA_BLO
|
||||
static bool gensec_gssapi_parse_krb5_wrap(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, DATA_BLOB *ticket, uint8_t tok_id[2])
|
||||
{
|
||||
bool ret = false;
|
||||
- struct asn1_data *data = asn1_init(mem_ctx);
|
||||
+ struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
|
||||
int data_remaining;
|
||||
|
||||
if (!data) {
|
||||
diff --git a/source4/ldap_server/ldap_server.c b/source4/ldap_server/ldap_server.c
|
||||
index 709b7bcacfa..6d329329909 100644
|
||||
--- a/source4/ldap_server/ldap_server.c
|
||||
+++ b/source4/ldap_server/ldap_server.c
|
||||
@@ -560,7 +560,7 @@ static void ldapsrv_call_read_done(struct tevent_req *subreq)
|
||||
return;
|
||||
}
|
||||
|
||||
- asn1 = asn1_init(call);
|
||||
+ asn1 = asn1_init(call, ASN1_MAX_TREE_DEPTH);
|
||||
if (asn1 == NULL) {
|
||||
ldapsrv_terminate_connection(conn, "no memory");
|
||||
return;
|
||||
diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c
|
||||
index da84adc7769..2d75af6af6e 100644
|
||||
--- a/source4/libcli/ldap/ldap_client.c
|
||||
+++ b/source4/libcli/ldap/ldap_client.c
|
||||
@@ -284,7 +284,7 @@ static void ldap_connection_recv_done(struct tevent_req *subreq)
|
||||
return;
|
||||
}
|
||||
|
||||
- asn1 = asn1_init(conn);
|
||||
+ asn1 = asn1_init(conn, ASN1_MAX_TREE_DEPTH);
|
||||
if (asn1 == NULL) {
|
||||
TALLOC_FREE(msg);
|
||||
ldap_error_handler(conn, NT_STATUS_NO_MEMORY);
|
||||
diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c
|
||||
index 716ca148308..df012a158e0 100644
|
||||
--- a/source4/libcli/ldap/ldap_controls.c
|
||||
+++ b/source4/libcli/ldap/ldap_controls.c
|
||||
@@ -32,7 +32,7 @@ static bool decode_server_sort_response(void *mem_ctx, DATA_BLOB in, void *_out)
|
||||
{
|
||||
void **out = (void **)_out;
|
||||
DATA_BLOB attr;
|
||||
- struct asn1_data *data = asn1_init(mem_ctx);
|
||||
+ struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
|
||||
struct ldb_sort_resp_control *lsrc;
|
||||
|
||||
if (!data) return false;
|
||||
@@ -79,7 +79,7 @@ static bool decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void *_out)
|
||||
void **out = (void **)_out;
|
||||
DATA_BLOB attr;
|
||||
DATA_BLOB rule;
|
||||
- struct asn1_data *data = asn1_init(mem_ctx);
|
||||
+ struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
|
||||
struct ldb_server_sort_control **lssc;
|
||||
int num;
|
||||
|
||||
@@ -166,7 +166,7 @@ static bool decode_extended_dn_request(void *mem_ctx, DATA_BLOB in, void *_out)
|
||||
return true;
|
||||
}
|
||||
|
||||
- data = asn1_init(mem_ctx);
|
||||
+ data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
|
||||
if (!data) return false;
|
||||
|
||||
if (!asn1_load(data, in)) {
|
||||
@@ -198,7 +198,7 @@ static bool decode_extended_dn_request(void *mem_ctx, DATA_BLOB in, void *_out)
|
||||
static bool decode_sd_flags_request(void *mem_ctx, DATA_BLOB in, void *_out)
|
||||
{
|
||||
void **out = (void **)_out;
|
||||
- struct asn1_data *data = asn1_init(mem_ctx);
|
||||
+ struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
|
||||
struct ldb_sd_flags_control *lsdfc;
|
||||
|
||||
if (!data) return false;
|
||||
@@ -232,7 +232,7 @@ static bool decode_sd_flags_request(void *mem_ctx, DATA_BLOB in, void *_out)
|
||||
static bool decode_search_options_request(void *mem_ctx, DATA_BLOB in, void *_out)
|
||||
{
|
||||
void **out = (void **)_out;
|
||||
- struct asn1_data *data = asn1_init(mem_ctx);
|
||||
+ struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
|
||||
struct ldb_search_options_control *lsoc;
|
||||
|
||||
if (!data) return false;
|
||||
@@ -267,7 +267,7 @@ static bool decode_paged_results_request(void *mem_ctx, DATA_BLOB in, void *_out
|
||||
{
|
||||
void **out = (void **)_out;
|
||||
DATA_BLOB cookie;
|
||||
- struct asn1_data *data = asn1_init(mem_ctx);
|
||||
+ struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
|
||||
struct ldb_paged_control *lprc;
|
||||
|
||||
if (!data) return false;
|
||||
@@ -316,7 +316,7 @@ static bool decode_dirsync_request(void *mem_ctx, DATA_BLOB in, void *_out)
|
||||
{
|
||||
void **out = (void **)_out;
|
||||
DATA_BLOB cookie;
|
||||
- struct asn1_data *data = asn1_init(mem_ctx);
|
||||
+ struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
|
||||
struct ldb_dirsync_control *ldc;
|
||||
|
||||
if (!data) return false;
|
||||
@@ -372,7 +372,7 @@ static bool decode_asq_control(void *mem_ctx, DATA_BLOB in, void *_out)
|
||||
{
|
||||
void **out = (void **)_out;
|
||||
DATA_BLOB source_attribute;
|
||||
- struct asn1_data *data = asn1_init(mem_ctx);
|
||||
+ struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
|
||||
struct ldb_asq_control *lac;
|
||||
|
||||
if (!data) return false;
|
||||
@@ -433,7 +433,7 @@ static bool decode_verify_name_request(void *mem_ctx, DATA_BLOB in, void *_out)
|
||||
{
|
||||
void **out = (void **)_out;
|
||||
DATA_BLOB name;
|
||||
- struct asn1_data *data = asn1_init(mem_ctx);
|
||||
+ struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
|
||||
struct ldb_verify_name_control *lvnc;
|
||||
int len;
|
||||
|
||||
@@ -485,7 +485,7 @@ static bool decode_verify_name_request(void *mem_ctx, DATA_BLOB in, void *_out)
|
||||
static bool encode_verify_name_request(void *mem_ctx, void *in, DATA_BLOB *out)
|
||||
{
|
||||
struct ldb_verify_name_control *lvnc = talloc_get_type(in, struct ldb_verify_name_control);
|
||||
- struct asn1_data *data = asn1_init(mem_ctx);
|
||||
+ struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
|
||||
DATA_BLOB gc_utf16;
|
||||
|
||||
if (!data) return false;
|
||||
@@ -528,7 +528,7 @@ static bool decode_vlv_request(void *mem_ctx, DATA_BLOB in, void *_out)
|
||||
{
|
||||
void **out = (void **)_out;
|
||||
DATA_BLOB assertion_value, context_id;
|
||||
- struct asn1_data *data = asn1_init(mem_ctx);
|
||||
+ struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
|
||||
struct ldb_vlv_req_control *lvrc;
|
||||
|
||||
if (!data) return false;
|
||||
@@ -626,7 +626,7 @@ static bool decode_vlv_response(void *mem_ctx, DATA_BLOB in, void *_out)
|
||||
{
|
||||
void **out = (void **)_out;
|
||||
DATA_BLOB context_id;
|
||||
- struct asn1_data *data = asn1_init(mem_ctx);
|
||||
+ struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
|
||||
struct ldb_vlv_resp_control *lvrc;
|
||||
|
||||
if (!data) return false;
|
||||
@@ -682,7 +682,7 @@ static bool decode_vlv_response(void *mem_ctx, DATA_BLOB in, void *_out)
|
||||
static bool encode_server_sort_response(void *mem_ctx, void *in, DATA_BLOB *out)
|
||||
{
|
||||
struct ldb_sort_resp_control *lsrc = talloc_get_type(in, struct ldb_sort_resp_control);
|
||||
- struct asn1_data *data = asn1_init(mem_ctx);
|
||||
+ struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
|
||||
|
||||
if (!data) return false;
|
||||
|
||||
@@ -716,7 +716,7 @@ static bool encode_server_sort_response(void *mem_ctx, void *in, DATA_BLOB *out)
|
||||
static bool encode_server_sort_request(void *mem_ctx, void *in, DATA_BLOB *out)
|
||||
{
|
||||
struct ldb_server_sort_control **lssc = talloc_get_type(in, struct ldb_server_sort_control *);
|
||||
- struct asn1_data *data = asn1_init(mem_ctx);
|
||||
+ struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
|
||||
int num;
|
||||
|
||||
if (!data) return false;
|
||||
@@ -782,7 +782,7 @@ static bool encode_extended_dn_request(void *mem_ctx, void *in, DATA_BLOB *out)
|
||||
return true;
|
||||
}
|
||||
|
||||
- data = asn1_init(mem_ctx);
|
||||
+ data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
|
||||
|
||||
if (!data) return false;
|
||||
|
||||
@@ -810,7 +810,7 @@ static bool encode_extended_dn_request(void *mem_ctx, void *in, DATA_BLOB *out)
|
||||
static bool encode_sd_flags_request(void *mem_ctx, void *in, DATA_BLOB *out)
|
||||
{
|
||||
struct ldb_sd_flags_control *lsdfc = talloc_get_type(in, struct ldb_sd_flags_control);
|
||||
- struct asn1_data *data = asn1_init(mem_ctx);
|
||||
+ struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
|
||||
|
||||
if (!data) return false;
|
||||
|
||||
@@ -838,7 +838,7 @@ static bool encode_sd_flags_request(void *mem_ctx, void *in, DATA_BLOB *out)
|
||||
static bool encode_search_options_request(void *mem_ctx, void *in, DATA_BLOB *out)
|
||||
{
|
||||
struct ldb_search_options_control *lsoc = talloc_get_type(in, struct ldb_search_options_control);
|
||||
- struct asn1_data *data = asn1_init(mem_ctx);
|
||||
+ struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
|
||||
|
||||
if (!data) return false;
|
||||
|
||||
@@ -866,7 +866,7 @@ static bool encode_search_options_request(void *mem_ctx, void *in, DATA_BLOB *ou
|
||||
static bool encode_paged_results_request(void *mem_ctx, void *in, DATA_BLOB *out)
|
||||
{
|
||||
struct ldb_paged_control *lprc = talloc_get_type(in, struct ldb_paged_control);
|
||||
- struct asn1_data *data = asn1_init(mem_ctx);
|
||||
+ struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
|
||||
|
||||
if (!data) return false;
|
||||
|
||||
@@ -901,7 +901,7 @@ static bool encode_paged_results_request(void *mem_ctx, void *in, DATA_BLOB *out
|
||||
static bool encode_asq_control(void *mem_ctx, void *in, DATA_BLOB *out)
|
||||
{
|
||||
struct ldb_asq_control *lac = talloc_get_type(in, struct ldb_asq_control);
|
||||
- struct asn1_data *data = asn1_init(mem_ctx);
|
||||
+ struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
|
||||
|
||||
if (!data) return false;
|
||||
|
||||
@@ -936,7 +936,7 @@ static bool encode_asq_control(void *mem_ctx, void *in, DATA_BLOB *out)
|
||||
static bool encode_dirsync_request(void *mem_ctx, void *in, DATA_BLOB *out)
|
||||
{
|
||||
struct ldb_dirsync_control *ldc = talloc_get_type(in, struct ldb_dirsync_control);
|
||||
- struct asn1_data *data = asn1_init(mem_ctx);
|
||||
+ struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
|
||||
|
||||
if (!data) return false;
|
||||
|
||||
@@ -972,7 +972,7 @@ static bool encode_dirsync_request(void *mem_ctx, void *in, DATA_BLOB *out)
|
||||
static bool encode_vlv_request(void *mem_ctx, void *in, DATA_BLOB *out)
|
||||
{
|
||||
struct ldb_vlv_req_control *lvrc = talloc_get_type(in, struct ldb_vlv_req_control);
|
||||
- struct asn1_data *data = asn1_init(mem_ctx);
|
||||
+ struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
|
||||
|
||||
if (!data) return false;
|
||||
|
||||
@@ -1040,7 +1040,7 @@ static bool encode_vlv_request(void *mem_ctx, void *in, DATA_BLOB *out)
|
||||
static bool encode_vlv_response(void *mem_ctx, void *in, DATA_BLOB *out)
|
||||
{
|
||||
struct ldb_vlv_resp_control *lvrc = talloc_get_type(in, struct ldb_vlv_resp_control);
|
||||
- struct asn1_data *data = asn1_init(mem_ctx);
|
||||
+ struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
|
||||
|
||||
if (!data) return false;
|
||||
|
||||
@@ -1083,7 +1083,7 @@ static bool encode_openldap_dereference(void *mem_ctx, void *in, DATA_BLOB *out)
|
||||
{
|
||||
struct dsdb_openldap_dereference_control *control = talloc_get_type(in, struct dsdb_openldap_dereference_control);
|
||||
int i,j;
|
||||
- struct asn1_data *data = asn1_init(mem_ctx);
|
||||
+ struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
|
||||
|
||||
if (!data) return false;
|
||||
|
||||
@@ -1132,7 +1132,7 @@ static bool encode_openldap_dereference(void *mem_ctx, void *in, DATA_BLOB *out)
|
||||
static bool decode_openldap_dereference(void *mem_ctx, DATA_BLOB in, void *_out)
|
||||
{
|
||||
void **out = (void **)_out;
|
||||
- struct asn1_data *data = asn1_init(mem_ctx);
|
||||
+ struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
|
||||
struct dsdb_openldap_dereference_result_control *control;
|
||||
struct dsdb_openldap_dereference_result **r = NULL;
|
||||
int i = 0;
|
||||
--
|
||||
2.17.1
|
||||
|
||||
|
||||
52
CVE-2020-10704-3.patch
Normal file
52
CVE-2020-10704-3.patch
Normal file
@ -0,0 +1,52 @@
|
||||
Backport of:
|
||||
|
||||
From d3be674c3ffa3541e2ba757e2c6dfb32508db440 Mon Sep 17 00:00:00 2001
|
||||
From: Gary Lockyer <gary@catalyst.net.nz>
|
||||
Date: Wed, 8 Apr 2020 15:30:52 +1200
|
||||
Subject: [PATCH 3/8] CVE-2020-10704: lib util asn1: Check parse tree depth
|
||||
|
||||
Check the current depth of the parse tree and reject the input if the
|
||||
depth exceeds that passed to asn1_init
|
||||
|
||||
Credit to OSS-Fuzz
|
||||
|
||||
REF: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=20454
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14334
|
||||
|
||||
Signed-off-by: Gary Lockyer <gary@catalyst.net.nz>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
---
|
||||
lib/util/asn1.c | 13 +++++++++++++
|
||||
selftest/knownfail.d/ldap_message | 2 --
|
||||
2 files changed, 13 insertions(+), 2 deletions(-)
|
||||
delete mode 100644 selftest/knownfail.d/ldap_message
|
||||
|
||||
--- a/lib/util/asn1.c
|
||||
+++ b/lib/util/asn1.c
|
||||
@@ -647,6 +647,16 @@ bool asn1_start_tag(struct asn1_data *da
|
||||
uint8_t b;
|
||||
struct nesting *nesting;
|
||||
|
||||
+ /*
|
||||
+ * Check the depth of the parse tree and prevent it from growing
|
||||
+ * too large.
|
||||
+ */
|
||||
+ data->depth++;
|
||||
+ if (data->depth > data->max_depth) {
|
||||
+ data->has_error = true;
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
if (!asn1_read_uint8(data, &b))
|
||||
return false;
|
||||
|
||||
@@ -703,6 +713,9 @@ bool asn1_end_tag(struct asn1_data *data
|
||||
{
|
||||
struct nesting *nesting;
|
||||
|
||||
+ if (data->depth > 0) {
|
||||
+ data->depth--;
|
||||
+ }
|
||||
/* make sure we read it all */
|
||||
if (asn1_tag_remaining(data) != 0) {
|
||||
data->has_error = true;
|
||||
96
CVE-2020-10704-5.patch
Normal file
96
CVE-2020-10704-5.patch
Normal file
@ -0,0 +1,96 @@
|
||||
From 9944df6ef1e421331ea1ca773f7e5652262d5d1b Mon Sep 17 00:00:00 2001
|
||||
From: Gary Lockyer <gary@catalyst.net.nz>
|
||||
Date: Tue, 7 Apr 2020 09:09:01 +1200
|
||||
Subject: [PATCH 5/8] CVE-2020-10704: smb.conf: Add max ldap request sizes
|
||||
|
||||
Add two new smb.conf parameters to control the maximum permitted ldap
|
||||
request size.
|
||||
|
||||
Adds:
|
||||
ldap max anonymous request size default 250Kb
|
||||
ldap max authenticated request size default 16Mb
|
||||
|
||||
Credit to OSS-Fuzz
|
||||
|
||||
REF: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=20454
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14334
|
||||
|
||||
Signed-off-by: Gary Lockyer <gary@catalyst.net.nz>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
---
|
||||
.../smbdotconf/ldap/ldapmaxanonrequest.xml | 18 ++++++++++++++++++
|
||||
.../smbdotconf/ldap/ldapmaxauthrequest.xml | 18 ++++++++++++++++++
|
||||
lib/param/loadparm.c | 5 +++++
|
||||
source3/param/loadparm.c | 3 +++
|
||||
4 files changed, 44 insertions(+)
|
||||
create mode 100644 docs-xml/smbdotconf/ldap/ldapmaxanonrequest.xml
|
||||
create mode 100644 docs-xml/smbdotconf/ldap/ldapmaxauthrequest.xml
|
||||
|
||||
--- /dev/null
|
||||
+++ b/docs-xml/smbdotconf/ldap/ldapmaxanonrequest.xml
|
||||
@@ -0,0 +1,18 @@
|
||||
+<samba:parameter name="ldap max anonymous request size"
|
||||
+ context="G"
|
||||
+ type="integer"
|
||||
+ xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
|
||||
+<description>
|
||||
+ <para>
|
||||
+ This parameter specifies the maximum permitted size (in bytes)
|
||||
+ for an LDAP request received on an anonymous connection.
|
||||
+ </para>
|
||||
+
|
||||
+ <para>
|
||||
+ If the request size exceeds this limit the request will be
|
||||
+ rejected.
|
||||
+ </para>
|
||||
+</description>
|
||||
+<value type="default">256000</value>
|
||||
+<value type="example">500000</value>
|
||||
+</samba:parameter>
|
||||
--- /dev/null
|
||||
+++ b/docs-xml/smbdotconf/ldap/ldapmaxauthrequest.xml
|
||||
@@ -0,0 +1,18 @@
|
||||
+<samba:parameter name="ldap max authenticated request size"
|
||||
+ context="G"
|
||||
+ type="integer"
|
||||
+ xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
|
||||
+<description>
|
||||
+ <para>
|
||||
+ This parameter specifies the maximum permitted size (in bytes)
|
||||
+ for an LDAP request received on an authenticated connection.
|
||||
+ </para>
|
||||
+
|
||||
+ <para>
|
||||
+ If the request size exceeds this limit the request will be
|
||||
+ rejected.
|
||||
+ </para>
|
||||
+</description>
|
||||
+<value type="default">16777216</value>
|
||||
+<value type="example">4194304</value>
|
||||
+</samba:parameter>
|
||||
--- a/lib/param/loadparm.c
|
||||
+++ b/lib/param/loadparm.c
|
||||
@@ -3027,6 +3027,11 @@ struct loadparm_context *loadparm_init(T
|
||||
|
||||
lpcfg_do_global_parameter(lp_ctx, "debug encryption", "no");
|
||||
|
||||
+ lpcfg_do_global_parameter(
|
||||
+ lp_ctx, "ldap max anonymous request size", "256000");
|
||||
+ lpcfg_do_global_parameter(
|
||||
+ lp_ctx, "ldap max authenticated request size", "16777216");
|
||||
+
|
||||
for (i = 0; parm_table[i].label; i++) {
|
||||
if (!(lp_ctx->flags[i] & FLAG_CMDLINE)) {
|
||||
lp_ctx->flags[i] |= FLAG_DEFAULT;
|
||||
--- a/source3/param/loadparm.c
|
||||
+++ b/source3/param/loadparm.c
|
||||
@@ -956,6 +956,9 @@ static void init_globals(struct loadparm
|
||||
Globals.prefork_backoff_increment = 10;
|
||||
Globals.prefork_maximum_backoff = 120;
|
||||
|
||||
+ Globals.ldap_max_anonymous_request_size = 256000;
|
||||
+ Globals.ldap_max_authenticated_request_size = 16777216;
|
||||
+
|
||||
/* Now put back the settings that were set with lp_set_cmdline() */
|
||||
apply_lp_set_cmdline();
|
||||
}
|
||||
163
CVE-2020-10704-6.patch
Normal file
163
CVE-2020-10704-6.patch
Normal file
@ -0,0 +1,163 @@
|
||||
Backport of:
|
||||
|
||||
From 85619363d3280346b2253fe44bf67d4881a53ebd Mon Sep 17 00:00:00 2001
|
||||
From: Gary Lockyer <gary@catalyst.net.nz>
|
||||
Date: Wed, 8 Apr 2020 15:32:22 +1200
|
||||
Subject: [PATCH 6/8] CVE-2020-10704: S4 ldap server: Limit request sizes
|
||||
|
||||
Check the size of authenticated and anonymous ldap requests and reject
|
||||
them if they exceed the limits in smb.conf
|
||||
|
||||
Credit to OSS-Fuzz
|
||||
|
||||
REF: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=20454
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14334
|
||||
|
||||
Signed-off-by: Gary Lockyer <gary@catalyst.net.nz>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
---
|
||||
selftest/knownfail.d/ldap_raw | 1 -
|
||||
source4/ldap_server/ldap_server.c | 96 ++++++++++++++++++++++++++++++-
|
||||
2 files changed, 95 insertions(+), 2 deletions(-)
|
||||
delete mode 100644 selftest/knownfail.d/ldap_raw
|
||||
|
||||
--- a/source4/ldap_server/ldap_server.c
|
||||
+++ b/source4/ldap_server/ldap_server.c
|
||||
@@ -441,6 +441,10 @@ static void ldapsrv_accept_tls_done(stru
|
||||
}
|
||||
|
||||
static void ldapsrv_call_read_done(struct tevent_req *subreq);
|
||||
+static NTSTATUS ldapsrv_packet_check(
|
||||
+ void *private_data,
|
||||
+ DATA_BLOB blob,
|
||||
+ size_t *packet_size);
|
||||
|
||||
static bool ldapsrv_call_read_next(struct ldapsrv_connection *conn)
|
||||
{
|
||||
@@ -494,7 +498,7 @@ static bool ldapsrv_call_read_next(struc
|
||||
conn->connection->event.ctx,
|
||||
conn->sockets.active,
|
||||
7, /* initial_read_size */
|
||||
- ldap_full_packet,
|
||||
+ ldapsrv_packet_check,
|
||||
conn);
|
||||
if (subreq == NULL) {
|
||||
ldapsrv_terminate_connection(conn, "ldapsrv_call_read_next: "
|
||||
@@ -520,6 +524,9 @@ static bool ldapsrv_call_read_next(struc
|
||||
}
|
||||
|
||||
static void ldapsrv_call_process_done(struct tevent_req *subreq);
|
||||
+static int ldapsrv_check_packet_size(
|
||||
+ struct ldapsrv_connection *conn,
|
||||
+ size_t size);
|
||||
|
||||
static void ldapsrv_call_read_done(struct tevent_req *subreq)
|
||||
{
|
||||
@@ -530,6 +537,7 @@ static void ldapsrv_call_read_done(struc
|
||||
struct ldapsrv_call *call;
|
||||
struct asn1_data *asn1;
|
||||
DATA_BLOB blob;
|
||||
+ int ret = LDAP_SUCCESS;
|
||||
|
||||
conn->sockets.read_req = NULL;
|
||||
|
||||
@@ -560,6 +568,14 @@ static void ldapsrv_call_read_done(struc
|
||||
return;
|
||||
}
|
||||
|
||||
+ ret = ldapsrv_check_packet_size(conn, blob.length);
|
||||
+ if (ret != LDAP_SUCCESS) {
|
||||
+ ldapsrv_terminate_connection(
|
||||
+ conn,
|
||||
+ "Request packet too large");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
asn1 = asn1_init(call, ASN1_MAX_TREE_DEPTH);
|
||||
if (asn1 == NULL) {
|
||||
ldapsrv_terminate_connection(conn, "no memory");
|
||||
@@ -1362,6 +1378,84 @@ static void ldapsrv_post_fork(struct tas
|
||||
}
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Check the size of an ldap request packet.
|
||||
+ *
|
||||
+ * For authenticated connections the maximum packet size is controlled by
|
||||
+ * the smb.conf parameter "ldap max authenticated request size"
|
||||
+ *
|
||||
+ * For anonymous connections the maximum packet size is controlled by
|
||||
+ * the smb.conf parameter "ldap max anonymous request size"
|
||||
+ */
|
||||
+static int ldapsrv_check_packet_size(
|
||||
+ struct ldapsrv_connection *conn,
|
||||
+ size_t size)
|
||||
+{
|
||||
+ bool is_anonymous = false;
|
||||
+ size_t max_size = 0;
|
||||
+
|
||||
+ max_size = lpcfg_ldap_max_anonymous_request_size(conn->lp_ctx);
|
||||
+ if (size <= max_size) {
|
||||
+ return LDAP_SUCCESS;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Request is larger than the maximum unauthenticated request size.
|
||||
+ * As this code is called frequently we avoid calling
|
||||
+ * security_token_is_anonymous if possible
|
||||
+ */
|
||||
+ if (conn->session_info != NULL &&
|
||||
+ conn->session_info->security_token != NULL) {
|
||||
+ is_anonymous = security_token_is_anonymous(
|
||||
+ conn->session_info->security_token);
|
||||
+ }
|
||||
+
|
||||
+ if (is_anonymous) {
|
||||
+ DBG_WARNING(
|
||||
+ "LDAP request size (%zu) exceeds (%zu)\n",
|
||||
+ size,
|
||||
+ max_size);
|
||||
+ return LDAP_UNWILLING_TO_PERFORM;
|
||||
+ }
|
||||
+
|
||||
+ max_size = lpcfg_ldap_max_authenticated_request_size(conn->lp_ctx);
|
||||
+ if (size > max_size) {
|
||||
+ DBG_WARNING(
|
||||
+ "LDAP request size (%zu) exceeds (%zu)\n",
|
||||
+ size,
|
||||
+ max_size);
|
||||
+ return LDAP_UNWILLING_TO_PERFORM;
|
||||
+ }
|
||||
+ return LDAP_SUCCESS;
|
||||
+
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Check that the blob contains enough data to be a valid packet
|
||||
+ * If there is a packet header check the size to ensure that it does not
|
||||
+ * exceed the maximum sizes.
|
||||
+ *
|
||||
+ */
|
||||
+static NTSTATUS ldapsrv_packet_check(
|
||||
+ void *private_data,
|
||||
+ DATA_BLOB blob,
|
||||
+ size_t *packet_size)
|
||||
+{
|
||||
+ NTSTATUS ret;
|
||||
+ struct ldapsrv_connection *conn = private_data;
|
||||
+ int result = LDB_SUCCESS;
|
||||
+
|
||||
+ ret = ldap_full_packet(private_data, blob, packet_size);
|
||||
+ if (!NT_STATUS_IS_OK(ret)) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+ result = ldapsrv_check_packet_size(conn, *packet_size);
|
||||
+ if (result != LDAP_SUCCESS) {
|
||||
+ return NT_STATUS_LDAP(result);
|
||||
+ }
|
||||
+ return NT_STATUS_OK;
|
||||
+}
|
||||
+
|
||||
NTSTATUS server_service_ldap_init(TALLOC_CTX *ctx)
|
||||
{
|
||||
static const struct service_details details = {
|
||||
211
CVE-2020-10704-7.patch
Normal file
211
CVE-2020-10704-7.patch
Normal file
@ -0,0 +1,211 @@
|
||||
Backport of:
|
||||
|
||||
From 9be121c7055fde841be15f8d570ff49801b68bff Mon Sep 17 00:00:00 2001
|
||||
From: Gary Lockyer <gary@catalyst.net.nz>
|
||||
Date: Wed, 8 Apr 2020 08:49:23 +1200
|
||||
Subject: [PATCH 7/8] CVE-2020-10704: libcli ldap_message: Add search size
|
||||
limits to ldap_decode
|
||||
|
||||
Add search request size limits to ldap_decode calls.
|
||||
|
||||
The ldap server uses the smb.conf variable
|
||||
"ldap max search request size" which defaults to 250Kb.
|
||||
For cldap the limit is hard coded as 4096.
|
||||
|
||||
Credit to OSS-Fuzz
|
||||
|
||||
REF: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=20454
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14334
|
||||
|
||||
Signed-off-by: Gary Lockyer <gary@catalyst.net.nz>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
---
|
||||
.../smbdotconf/ldap/ldapmaxsearchrequest.xml | 18 ++++++++++++++
|
||||
lib/param/loadparm.c | 2 ++
|
||||
libcli/cldap/cldap.c | 18 +++++++++++---
|
||||
libcli/ldap/ldap_message.c | 1 +
|
||||
libcli/ldap/ldap_message.h | 5 ++++
|
||||
libcli/ldap/tests/ldap_message_test.c | 24 +++++++++++++++----
|
||||
source3/param/loadparm.c | 1 +
|
||||
source4/ldap_server/ldap_server.c | 10 ++++++--
|
||||
source4/libcli/ldap/ldap_client.c | 3 ++-
|
||||
9 files changed, 72 insertions(+), 10 deletions(-)
|
||||
create mode 100644 docs-xml/smbdotconf/ldap/ldapmaxsearchrequest.xml
|
||||
|
||||
--- /dev/null
|
||||
+++ b/docs-xml/smbdotconf/ldap/ldapmaxsearchrequest.xml
|
||||
@@ -0,0 +1,18 @@
|
||||
+<samba:parameter name="ldap max search request size"
|
||||
+ context="G"
|
||||
+ type="integer"
|
||||
+ xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
|
||||
+<description>
|
||||
+ <para>
|
||||
+ This parameter specifies the maximum permitted size (in bytes)
|
||||
+ for an LDAP search request.
|
||||
+ </para>
|
||||
+
|
||||
+ <para>
|
||||
+ If the request size exceeds this limit the request will be
|
||||
+ rejected.
|
||||
+ </para>
|
||||
+</description>
|
||||
+<value type="default">256000</value>
|
||||
+<value type="example">4194304</value>
|
||||
+</samba:parameter>
|
||||
--- a/lib/param/loadparm.c
|
||||
+++ b/lib/param/loadparm.c
|
||||
@@ -3031,6 +3031,8 @@ struct loadparm_context *loadparm_init(T
|
||||
lp_ctx, "ldap max anonymous request size", "256000");
|
||||
lpcfg_do_global_parameter(
|
||||
lp_ctx, "ldap max authenticated request size", "16777216");
|
||||
+ lpcfg_do_global_parameter(
|
||||
+ lp_ctx, "ldap max search request size", "256000");
|
||||
|
||||
for (i = 0; parm_table[i].label; i++) {
|
||||
if (!(lp_ctx->flags[i] & FLAG_CMDLINE)) {
|
||||
--- a/libcli/cldap/cldap.c
|
||||
+++ b/libcli/cldap/cldap.c
|
||||
@@ -111,6 +111,11 @@ struct cldap_search_state {
|
||||
struct tevent_req *req;
|
||||
};
|
||||
|
||||
+/*
|
||||
+ * For CLDAP we limit the maximum search request size to 4kb
|
||||
+ */
|
||||
+#define MAX_SEARCH_REQUEST 4096
|
||||
+
|
||||
static int cldap_socket_destructor(struct cldap_socket *c)
|
||||
{
|
||||
while (c->searches.list) {
|
||||
@@ -224,6 +229,9 @@ static bool cldap_socket_recv_dgram(stru
|
||||
void *p;
|
||||
struct cldap_search_state *search;
|
||||
NTSTATUS status;
|
||||
+ struct ldap_request_limits limits = {
|
||||
+ .max_search_size = MAX_SEARCH_REQUEST
|
||||
+ };
|
||||
|
||||
if (in->recv_errno != 0) {
|
||||
goto error;
|
||||
@@ -242,7 +250,7 @@ static bool cldap_socket_recv_dgram(stru
|
||||
}
|
||||
|
||||
/* this initial decode is used to find the message id */
|
||||
- status = ldap_decode(asn1, NULL, in->ldap_msg);
|
||||
+ status = ldap_decode(asn1, &limits, NULL, in->ldap_msg);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
goto nterror;
|
||||
}
|
||||
@@ -770,6 +778,9 @@ NTSTATUS cldap_search_recv(struct tevent
|
||||
struct cldap_search_state);
|
||||
struct ldap_message *ldap_msg;
|
||||
NTSTATUS status;
|
||||
+ struct ldap_request_limits limits = {
|
||||
+ .max_search_size = MAX_SEARCH_REQUEST
|
||||
+ };
|
||||
|
||||
if (tevent_req_is_nterror(req, &status)) {
|
||||
goto failed;
|
||||
@@ -780,7 +791,7 @@ NTSTATUS cldap_search_recv(struct tevent
|
||||
goto nomem;
|
||||
}
|
||||
|
||||
- status = ldap_decode(state->response.asn1, NULL, ldap_msg);
|
||||
+ status = ldap_decode(state->response.asn1, &limits, NULL, ldap_msg);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
goto failed;
|
||||
}
|
||||
@@ -796,7 +807,8 @@ NTSTATUS cldap_search_recv(struct tevent
|
||||
*io->out.response = ldap_msg->r.SearchResultEntry;
|
||||
|
||||
/* decode the 2nd part */
|
||||
- status = ldap_decode(state->response.asn1, NULL, ldap_msg);
|
||||
+ status = ldap_decode(
|
||||
+ state->response.asn1, &limits, NULL, ldap_msg);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
goto failed;
|
||||
}
|
||||
--- a/libcli/ldap/ldap_message.c
|
||||
+++ b/libcli/ldap/ldap_message.c
|
||||
@@ -1162,6 +1162,7 @@ static bool ldap_decode_attribs(TALLOC_C
|
||||
/* This routine returns LDAP status codes */
|
||||
|
||||
_PUBLIC_ NTSTATUS ldap_decode(struct asn1_data *data,
|
||||
+ const struct ldap_request_limits *limits,
|
||||
const struct ldap_control_handler *control_handlers,
|
||||
struct ldap_message *msg)
|
||||
{
|
||||
--- a/libcli/ldap/ldap_message.h
|
||||
+++ b/libcli/ldap/ldap_message.h
|
||||
@@ -213,10 +213,15 @@ struct ldap_control_handler {
|
||||
bool (*encode)(void *mem_ctx, void *in, DATA_BLOB *out);
|
||||
};
|
||||
|
||||
+struct ldap_request_limits {
|
||||
+ unsigned max_search_size;
|
||||
+};
|
||||
+
|
||||
struct asn1_data;
|
||||
|
||||
struct ldap_message *new_ldap_message(TALLOC_CTX *mem_ctx);
|
||||
NTSTATUS ldap_decode(struct asn1_data *data,
|
||||
+ const struct ldap_request_limits *limits,
|
||||
const struct ldap_control_handler *control_handlers,
|
||||
struct ldap_message *msg);
|
||||
bool ldap_encode(struct ldap_message *msg,
|
||||
--- a/source3/param/loadparm.c
|
||||
+++ b/source3/param/loadparm.c
|
||||
@@ -958,6 +958,7 @@ static void init_globals(struct loadparm
|
||||
|
||||
Globals.ldap_max_anonymous_request_size = 256000;
|
||||
Globals.ldap_max_authenticated_request_size = 16777216;
|
||||
+ Globals.ldap_max_search_request_size = 256000;
|
||||
|
||||
/* Now put back the settings that were set with lp_set_cmdline() */
|
||||
apply_lp_set_cmdline();
|
||||
--- a/source4/ldap_server/ldap_server.c
|
||||
+++ b/source4/ldap_server/ldap_server.c
|
||||
@@ -538,6 +538,7 @@ static void ldapsrv_call_read_done(struc
|
||||
struct asn1_data *asn1;
|
||||
DATA_BLOB blob;
|
||||
int ret = LDAP_SUCCESS;
|
||||
+ struct ldap_request_limits limits = {0};
|
||||
|
||||
conn->sockets.read_req = NULL;
|
||||
|
||||
@@ -593,8 +594,13 @@ static void ldapsrv_call_read_done(struc
|
||||
return;
|
||||
}
|
||||
|
||||
- status = ldap_decode(asn1, samba_ldap_control_handlers(),
|
||||
- call->request);
|
||||
+ limits.max_search_size =
|
||||
+ lpcfg_ldap_max_search_request_size(conn->lp_ctx);
|
||||
+ status = ldap_decode(
|
||||
+ asn1,
|
||||
+ &limits,
|
||||
+ samba_ldap_control_handlers(),
|
||||
+ call->request);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
ldapsrv_terminate_connection(conn, nt_errstr(status));
|
||||
return;
|
||||
--- a/source4/libcli/ldap/ldap_client.c
|
||||
+++ b/source4/libcli/ldap/ldap_client.c
|
||||
@@ -277,6 +277,7 @@ static void ldap_connection_recv_done(st
|
||||
struct ldap_message *msg;
|
||||
struct asn1_data *asn1;
|
||||
DATA_BLOB blob;
|
||||
+ struct ldap_request_limits limits = {0};
|
||||
|
||||
msg = talloc_zero(conn, struct ldap_message);
|
||||
if (msg == NULL) {
|
||||
@@ -306,7 +307,7 @@ static void ldap_connection_recv_done(st
|
||||
|
||||
asn1_load_nocopy(asn1, blob.data, blob.length);
|
||||
|
||||
- status = ldap_decode(asn1, samba_ldap_control_handlers(), msg);
|
||||
+ status = ldap_decode(asn1, &limits, samba_ldap_control_handlers(), msg);
|
||||
asn1_free(asn1);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
TALLOC_FREE(msg);
|
||||
66
CVE-2020-10704-8.patch
Normal file
66
CVE-2020-10704-8.patch
Normal file
@ -0,0 +1,66 @@
|
||||
From ee3156c76b86c11829f6f3fe1e3c940b45899c56 Mon Sep 17 00:00:00 2001
|
||||
From: Gary Lockyer <gary@catalyst.net.nz>
|
||||
Date: Wed, 8 Apr 2020 10:46:44 +1200
|
||||
Subject: [PATCH 8/8] CVE-2020-10704 libcli ldap: Check search request lengths.
|
||||
|
||||
Check the search request lengths against the limits passed to
|
||||
ldap_decode.
|
||||
|
||||
Credit to OSS-Fuzz
|
||||
|
||||
REF: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=20454
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14334
|
||||
|
||||
Signed-off-by: Gary Lockyer <gary@catalyst.net.nz>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
---
|
||||
lib/util/asn1.c | 7 +++++++
|
||||
lib/util/asn1.h | 1 +
|
||||
libcli/ldap/ldap_message.c | 4 ++++
|
||||
3 files changed, 12 insertions(+)
|
||||
|
||||
diff --git a/lib/util/asn1.c b/lib/util/asn1.c
|
||||
index ee3cff9cb65..32d7981d28f 100644
|
||||
--- a/lib/util/asn1.c
|
||||
+++ b/lib/util/asn1.c
|
||||
@@ -1159,3 +1159,10 @@ int asn1_peek_full_tag(DATA_BLOB blob, uint8_t tag, size_t *packet_size)
|
||||
*packet_size = size;
|
||||
return 0;
|
||||
}
|
||||
+
|
||||
+/*
|
||||
+ * Get the length of the ASN.1 data
|
||||
+ */
|
||||
+size_t asn1_get_length(const struct asn1_data *asn1) {
|
||||
+ return asn1->length;
|
||||
+}
|
||||
diff --git a/lib/util/asn1.h b/lib/util/asn1.h
|
||||
index fc365724e93..de92a767f14 100644
|
||||
--- a/lib/util/asn1.h
|
||||
+++ b/lib/util/asn1.h
|
||||
@@ -106,5 +106,6 @@ bool asn1_extract_blob(struct asn1_data *asn1, TALLOC_CTX *mem_ctx,
|
||||
DATA_BLOB *pblob);
|
||||
void asn1_load_nocopy(struct asn1_data *data, uint8_t *buf, size_t len);
|
||||
int asn1_peek_full_tag(DATA_BLOB blob, uint8_t tag, size_t *packet_size);
|
||||
+size_t asn1_get_length(const struct asn1_data *asn1);
|
||||
|
||||
#endif /* _ASN_1_H */
|
||||
diff --git a/libcli/ldap/ldap_message.c b/libcli/ldap/ldap_message.c
|
||||
index d38fa0b3b61..69a48279532 100644
|
||||
--- a/libcli/ldap/ldap_message.c
|
||||
+++ b/libcli/ldap/ldap_message.c
|
||||
@@ -1259,7 +1259,11 @@ _PUBLIC_ NTSTATUS ldap_decode(struct asn1_data *data,
|
||||
struct ldap_SearchRequest *r = &msg->r.SearchRequest;
|
||||
int sizelimit, timelimit;
|
||||
const char **attrs = NULL;
|
||||
+ size_t request_size = asn1_get_length(data);
|
||||
msg->type = LDAP_TAG_SearchRequest;
|
||||
+ if (request_size > limits->max_search_size) {
|
||||
+ goto prot_err;
|
||||
+ }
|
||||
if (!asn1_start_tag(data, tag)) goto prot_err;
|
||||
if (!asn1_read_OctetString_talloc(msg, data, &r->basedn)) goto prot_err;
|
||||
if (!asn1_read_enumerated(data, (int *)(void *)&(r->scope))) goto prot_err;
|
||||
--
|
||||
2.17.1
|
||||
|
||||
13
samba.spec
13
samba.spec
@ -49,7 +49,7 @@
|
||||
|
||||
Name: samba
|
||||
Version: 4.11.6
|
||||
Release: 5
|
||||
Release: 6
|
||||
|
||||
Summary: A suite for Linux to interoperate with Windows
|
||||
License: GPLv3+ and LGPLv3+
|
||||
@ -69,6 +69,14 @@ Source201: README.downgrade
|
||||
Patch100: 0000-use-gnutls-for-des-cbc.patch
|
||||
Patch101: 0001-handle-removal-des-enctypes-from-krb5.patch
|
||||
Patch102: 0002-samba-tool-create-working-private-krb5.conf.patch
|
||||
Patch103: CVE-2020-10700-1.patch
|
||||
Patch104: CVE-2020-10700-3.patch
|
||||
Patch105: CVE-2020-10704-1.patch
|
||||
Patch106: CVE-2020-10704-3.patch
|
||||
Patch107: CVE-2020-10704-5.patch
|
||||
Patch108: CVE-2020-10704-6.patch
|
||||
Patch109: CVE-2020-10704-7.patch
|
||||
Patch110: CVE-2020-10704-8.patch
|
||||
|
||||
BuildRequires: avahi-devel cups-devel dbus-devel docbook-style-xsl e2fsprogs-devel gawk gnupg2 gnutls-devel >= 3.4.7 gpgme-devel
|
||||
BuildRequires: jansson-devel krb5-devel >= %{required_mit_krb5} libacl-devel libaio-devel libarchive-devel libattr-devel
|
||||
@ -3079,6 +3087,9 @@ fi
|
||||
%{_mandir}/man8/*
|
||||
|
||||
%changelog
|
||||
* Wed May 20 2020 zhouyihang <zhouyihang3@huawei.com> - 4.11.6-6
|
||||
- fix CVE-2020-10700,CVE-2020-10704
|
||||
|
||||
* Sat Mar 21 2020 songnannan <songnannan2@huawei.com> - 4.11.6-5
|
||||
- bugfix about update
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user