Blame SOURCES/CVE-2021-20277.patch

fe9f52
From 3895ccd4de3fd5d900b7c1122d912f0a06c2b069 Mon Sep 17 00:00:00 2001
fe9f52
From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
fe9f52
Date: Fri, 5 Mar 2021 15:47:56 +1300
fe9f52
Subject: [PATCH 1/4] ldb: add tests for ldb_wildcard_compare
fe9f52
MIME-Version: 1.0
fe9f52
Content-Type: text/plain; charset=UTF-8
fe9f52
Content-Transfer-Encoding: 8bit
fe9f52
fe9f52
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14044
fe9f52
fe9f52
Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
fe9f52
Reviewed-by: Björn Jacke <bjacke@samba.org>
fe9f52
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
fe9f52
fe9f52
(cherry-picked from commit 33a95a1e75b85e9795c4490b78ead2162e2a1f47)
fe9f52
---
fe9f52
 lib/ldb/tests/ldb_match_test.c | 134 ++++++++++++++++++++++++++++++---
fe9f52
 1 file changed, 124 insertions(+), 10 deletions(-)
fe9f52
fe9f52
diff --git a/tests/ldb_match_test.c b/tests/ldb_match_test.c
fe9f52
index e09f50c86ba..3028aed072c 100644
fe9f52
--- a/tests/ldb_match_test.c
fe9f52
+++ b/tests/ldb_match_test.c
fe9f52
@@ -91,6 +91,33 @@ static int teardown(void **state)
fe9f52
 	return 0;
fe9f52
 }
fe9f52
 
fe9f52
+static void escape_string(uint8_t *buf, size_t buflen,
fe9f52
+			  const uint8_t *s, size_t len)
fe9f52
+{
fe9f52
+	size_t i;
fe9f52
+	size_t j = 0;
fe9f52
+	for (i = 0; i < len; i++) {
fe9f52
+		if (j == buflen - 1) {
fe9f52
+			goto fin;
fe9f52
+		}
fe9f52
+		if (s[i] >= 0x20) {
fe9f52
+			buf[j] = s[i];
fe9f52
+			j++;
fe9f52
+		} else {
fe9f52
+			if (j >= buflen - 4) {
fe9f52
+				goto fin;
fe9f52
+			}
fe9f52
+			/* utf-8 control char representation */
fe9f52
+			buf[j] = 0xE2;
fe9f52
+			buf[j + 1] = 0x90;
fe9f52
+			buf[j + 2] = 0x80 + s[i];
fe9f52
+			j+= 3;
fe9f52
+		}
fe9f52
+	}
fe9f52
+fin:
fe9f52
+	buf[j] = 0;
fe9f52
+}
fe9f52
+
fe9f52
 
fe9f52
 /*
fe9f52
  * The wild card pattern "attribute=*" is parsed as an LDB_OP_PRESENT operation
fe9f52
@@ -122,23 +149,110 @@ static void test_wildcard_match_star(void **state)
fe9f52
  * Test basic wild card matching
fe9f52
  *
fe9f52
  */
fe9f52
+struct wildcard_test {
fe9f52
+	uint8_t *val;
fe9f52
+	size_t val_size;
fe9f52
+	const char *search;
fe9f52
+	bool should_match;
fe9f52
+	bool fold;
fe9f52
+};
fe9f52
+
fe9f52
+/*
fe9f52
+ * Q: Why this macro rather than plain struct values?
fe9f52
+ * A: So we can get the size of the const char[] value while it is still a
fe9f52
+ * true array, not a pointer.
fe9f52
+ *
fe9f52
+ * Q: but why not just use strlen?
fe9f52
+ * A: so values can contain '\0', which we supposedly allow.
fe9f52
+ */
fe9f52
+
fe9f52
+#define TEST_ENTRY(val, search, should_match, fold)	\
fe9f52
+	{						\
fe9f52
+		(uint8_t*)discard_const(val),		\
fe9f52
+		sizeof(val) - 1,			\
fe9f52
+		search,					\
fe9f52
+		should_match,				\
fe9f52
+		fold					\
fe9f52
+	 }
fe9f52
+
fe9f52
 static void test_wildcard_match(void **state)
fe9f52
 {
fe9f52
 	struct ldbtest_ctx *ctx = *state;
fe9f52
-	bool matched = false;
fe9f52
-
fe9f52
-	uint8_t value[] = "The value.......end";
fe9f52
-	struct ldb_val val = {
fe9f52
-		.data   = value,
fe9f52
-		.length = (sizeof(value))
fe9f52
+	size_t failed = 0;
fe9f52
+	size_t i;
fe9f52
+	struct wildcard_test tests[] = {
fe9f52
+		TEST_ENTRY("The value.......end", "*end", true, true),
fe9f52
+		TEST_ENTRY("The value.......end", "*fend", false, true),
fe9f52
+		TEST_ENTRY("The value.......end", "*eel", false, true),
fe9f52
+		TEST_ENTRY("The value.......end", "*d", true, true),
fe9f52
+		TEST_ENTRY("The value.......end", "*D*", true, true),
fe9f52
+		TEST_ENTRY("The value.......end", "*e*d*", true, true),
fe9f52
+		TEST_ENTRY("end", "*e*d*", true, true),
fe9f52
+		TEST_ENTRY("end", "  *e*d*", true, true),
fe9f52
+		TEST_ENTRY("1.0.0.0.0.0.0.0aaaaaaaaaaaa", "*aaaaa", true, true),
fe9f52
+		TEST_ENTRY("1.0..0.0.0.0.0.0.0aAaaaAAAAAAA", "*a", true,  true),
fe9f52
+		TEST_ENTRY("1.0.0.0.0.0.0.0.0.0.0aaaa", "*aaaaa", false, true),
fe9f52
+		TEST_ENTRY("1.0.0.0.0.0.0.0.0.0.0", "*0.0", true, true),
fe9f52
+		TEST_ENTRY("1.0.0.0.0.0.0.0.0.0.0", "*0.0.0", true, true),
fe9f52
+		TEST_ENTRY("1.0.0.0.0.0.0.0.0.0", "1*0*0*0*0*0*0*0*0*0", true,
fe9f52
+			   true),
fe9f52
+		TEST_ENTRY("1.0.0.0.0.0.0.0.0", "1*0*0*0*0*0*0*0*0*0", false,
fe9f52
+			   true),
fe9f52
+		TEST_ENTRY("1.0.0.0.000.0.0.0.0", "1*0*0*0*0*0*0*0*0*0", true,
fe9f52
+			   true),
fe9f52
+		TEST_ENTRY("1\n0\r0\t000.0.0.0.0", "1*0*0*0*0*0*0*0*0", true,
fe9f52
+			   true),
fe9f52
+		/*
fe9f52
+		 *  We allow NUL bytes in non-casefolding syntaxes.
fe9f52
+		 */
fe9f52
+		TEST_ENTRY("1\x00 x", "1*x", true, false),
fe9f52
+		TEST_ENTRY("1\x00 x", "*x", true, false),
fe9f52
+		TEST_ENTRY("1\x00 x", "*x*", true, false),
fe9f52
+		TEST_ENTRY("1\x00 x", "* *", true, false),
fe9f52
+		TEST_ENTRY("1\x00 x", "1*", true, false),
fe9f52
+		TEST_ENTRY("1\x00 b* x", "1*b*", true, false),
fe9f52
+		TEST_ENTRY("1.0..0.0.0.0.0.0.0aAaaaAAAAAAA", "*a", false,  false),
fe9f52
 	};
fe9f52
-	struct ldb_parse_tree *tree = ldb_parse_tree(ctx, "objectClass=*end");
fe9f52
-	assert_non_null(tree);
fe9f52
 
fe9f52
-	ldb_wildcard_compare(ctx->ldb, tree, val, &matched);
fe9f52
-	assert_true(matched);
fe9f52
+	for (i = 0; i < ARRAY_SIZE(tests); i++) {
fe9f52
+		bool matched;
fe9f52
+		int ret;
fe9f52
+		struct ldb_val val = {
fe9f52
+			.data   = (uint8_t *)tests[i].val,
fe9f52
+			.length = tests[i].val_size
fe9f52
+		};
fe9f52
+		const char *attr = tests[i].fold ? "objectclass" : "birthLocation";
fe9f52
+		const char *s = talloc_asprintf(ctx, "%s=%s",
fe9f52
+						attr, tests[i].search);
fe9f52
+		struct ldb_parse_tree *tree = ldb_parse_tree(ctx, s);
fe9f52
+		assert_non_null(tree);
fe9f52
+		ret = ldb_wildcard_compare(ctx->ldb, tree, val, &matched);
fe9f52
+		if (ret != LDB_SUCCESS) {
fe9f52
+			uint8_t buf[100];
fe9f52
+			escape_string(buf, sizeof(buf),
fe9f52
+				      tests[i].val, tests[i].val_size);
fe9f52
+			print_error("%zu val: «%s», search «%s» FAILED with %d\n",
fe9f52
+				    i, buf, tests[i].search, ret);
fe9f52
+			failed++;
fe9f52
+		}
fe9f52
+		if (matched != tests[i].should_match) {
fe9f52
+			uint8_t buf[100];
fe9f52
+			escape_string(buf, sizeof(buf),
fe9f52
+				      tests[i].val, tests[i].val_size);
fe9f52
+			print_error("%zu val: «%s», search «%s» should %s\n",
fe9f52
+				    i, buf, tests[i].search,
fe9f52
+				    matched ? "not match" : "match");
fe9f52
+			failed++;
fe9f52
+		}
fe9f52
+	}
fe9f52
+	if (failed != 0) {
fe9f52
+		fail_msg("wrong results for %zu/%zu wildcard searches\n",
fe9f52
+			 failed, ARRAY_SIZE(tests));
fe9f52
+	}
fe9f52
 }
fe9f52
 
fe9f52
+#undef TEST_ENTRY
fe9f52
+
fe9f52
 
fe9f52
 /*
fe9f52
  * ldb_handler_copy and ldb_val_dup over allocate by one and add a trailing '\0'
fe9f52
-- 
fe9f52
2.25.1
fe9f52
fe9f52
fe9f52
From 984842f9881e7e72b1bcd032ad0245d08f79888d Mon Sep 17 00:00:00 2001
fe9f52
From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
fe9f52
Date: Fri, 5 Mar 2021 20:13:01 +1300
fe9f52
Subject: [PATCH 2/4] CVE-2021-20277 ldb tests: ldb_match tests with extra
fe9f52
 spaces
fe9f52
fe9f52
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14655
fe9f52
fe9f52
Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
fe9f52
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
fe9f52
(cherry-picked from commit for master)
fe9f52
---
fe9f52
 lib/ldb/tests/ldb_match_test.c | 8 +++++++-
fe9f52
 1 file changed, 7 insertions(+), 1 deletion(-)
fe9f52
fe9f52
diff --git a/tests/ldb_match_test.c b/tests/ldb_match_test.c
fe9f52
index 3028aed072c..ba6ea56be15 100644
fe9f52
--- a/tests/ldb_match_test.c
fe9f52
+++ b/tests/ldb_match_test.c
fe9f52
@@ -181,6 +181,8 @@ static void test_wildcard_match(void **state)
fe9f52
 	size_t failed = 0;
fe9f52
 	size_t i;
fe9f52
 	struct wildcard_test tests[] = {
fe9f52
+		TEST_ENTRY("                     1  0", "1*0*", true, true),
fe9f52
+		TEST_ENTRY("                     1  0", "1 *0", true, true),
fe9f52
 		TEST_ENTRY("The value.......end", "*end", true, true),
fe9f52
 		TEST_ENTRY("The value.......end", "*fend", false, true),
fe9f52
 		TEST_ENTRY("The value.......end", "*eel", false, true),
fe9f52
@@ -203,8 +205,12 @@ static void test_wildcard_match(void **state)
fe9f52
 		TEST_ENTRY("1\n0\r0\t000.0.0.0.0", "1*0*0*0*0*0*0*0*0", true,
fe9f52
 			   true),
fe9f52
 		/*
fe9f52
-		 *  We allow NUL bytes in non-casefolding syntaxes.
fe9f52
+		 *  We allow NUL bytes and redundant spaces in non-casefolding
fe9f52
+		 *  syntaxes.
fe9f52
 		 */
fe9f52
+		TEST_ENTRY("                  1  0", "*1  0", true, false),
fe9f52
+		TEST_ENTRY("                  1  0", "*1  0", true, false),
fe9f52
+		TEST_ENTRY("1    0", "*1 0", false, false),
fe9f52
 		TEST_ENTRY("1\x00 x", "1*x", true, false),
fe9f52
 		TEST_ENTRY("1\x00 x", "*x", true, false),
fe9f52
 		TEST_ENTRY("1\x00 x", "*x*", true, false),
fe9f52
-- 
fe9f52
2.25.1
fe9f52
fe9f52
fe9f52
From a3ea9b5cfd98e9c62d99b42e7ebd4af1549a0d26 Mon Sep 17 00:00:00 2001
fe9f52
From: Andrew Bartlett <abartlet@samba.org>
fe9f52
Date: Fri, 12 Mar 2021 11:51:56 +1300
fe9f52
Subject: [PATCH 3/4] CVE-2021-20277 ldb: Remove tests from ldb_match_test that
fe9f52
 do not pass
fe9f52
fe9f52
This reverts some of the backport of 33a95a1e75b85e9795c4490b78ead2162e2a1f47
fe9f52
fe9f52
This is done here rather than squashed in the cherry-pick of the expanded testsuite
fe9f52
because it allows this commit to be simply reverted for the backport of bug 14044
fe9f52
if this lands first, or to be dropped if bug 14044 lands first.
fe9f52
fe9f52
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14655
fe9f52
fe9f52
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
fe9f52
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
fe9f52
---
fe9f52
 lib/ldb/tests/ldb_match_test.c | 2 --
fe9f52
 1 file changed, 2 deletions(-)
fe9f52
fe9f52
diff --git a/tests/ldb_match_test.c b/tests/ldb_match_test.c
fe9f52
index ba6ea56be15..fbf4106fa78 100644
fe9f52
--- a/tests/ldb_match_test.c
fe9f52
+++ b/tests/ldb_match_test.c
fe9f52
@@ -191,11 +191,9 @@ static void test_wildcard_match(void **state)
fe9f52
 		TEST_ENTRY("The value.......end", "*e*d*", true, true),
fe9f52
 		TEST_ENTRY("end", "*e*d*", true, true),
fe9f52
 		TEST_ENTRY("end", "  *e*d*", true, true),
fe9f52
-		TEST_ENTRY("1.0.0.0.0.0.0.0aaaaaaaaaaaa", "*aaaaa", true, true),
fe9f52
 		TEST_ENTRY("1.0..0.0.0.0.0.0.0aAaaaAAAAAAA", "*a", true,  true),
fe9f52
 		TEST_ENTRY("1.0.0.0.0.0.0.0.0.0.0aaaa", "*aaaaa", false, true),
fe9f52
 		TEST_ENTRY("1.0.0.0.0.0.0.0.0.0.0", "*0.0", true, true),
fe9f52
-		TEST_ENTRY("1.0.0.0.0.0.0.0.0.0.0", "*0.0.0", true, true),
fe9f52
 		TEST_ENTRY("1.0.0.0.0.0.0.0.0.0", "1*0*0*0*0*0*0*0*0*0", true,
fe9f52
 			   true),
fe9f52
 		TEST_ENTRY("1.0.0.0.0.0.0.0.0", "1*0*0*0*0*0*0*0*0*0", false,
fe9f52
-- 
fe9f52
2.25.1
fe9f52
fe9f52
fe9f52
From 8fc0753ae7e2a2101c52574886e975ec8e90aee1 Mon Sep 17 00:00:00 2001
fe9f52
From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
fe9f52
Date: Tue, 8 Dec 2020 21:32:09 +1300
fe9f52
Subject: [PATCH 4/4] CVE-2021-20277 ldb/attrib_handlers casefold: stay in
fe9f52
 bounds
fe9f52
fe9f52
For a string that had N spaces at the beginning, we would
fe9f52
try to move N bytes beyond the end of the string.
fe9f52
fe9f52
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14655
fe9f52
fe9f52
Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
fe9f52
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
fe9f52
fe9f52
(cherry-picked from commit for master)
fe9f52
---
fe9f52
 lib/ldb/common/attrib_handlers.c | 2 +-
fe9f52
 1 file changed, 1 insertion(+), 1 deletion(-)
fe9f52
fe9f52
diff --git a/common/attrib_handlers.c b/common/attrib_handlers.c
fe9f52
index b5212b73159..c6ef5ad477b 100644
fe9f52
--- a/common/attrib_handlers.c
fe9f52
+++ b/common/attrib_handlers.c
fe9f52
@@ -76,7 +76,7 @@ int ldb_handler_fold(struct ldb_context *ldb, void *mem_ctx,
fe9f52
 	
fe9f52
 	/* remove leading spaces if any */
fe9f52
 	if (*s == ' ') {
fe9f52
-		for (t = s; *s == ' '; s++) ;
fe9f52
+		for (t = s; *s == ' '; s++, l--) ;
fe9f52
 
fe9f52
 		/* remove leading spaces by moving down the string */
fe9f52
 		memmove(t, s, l);
fe9f52
-- 
fe9f52
2.25.1
fe9f52