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