backport fo fix fuzz error:
idl: drsuapi_DsaAddressListItem_V1 limit recursion idl: limit recurion on recursive-elements lib: ldb Limit depth of ldb_parse_tree librpc: ndr add recursion check macros librpc: ndr Heap-buffer-overflow in lzxpress_decompress librpc: ndr NDR_PULL_ALIGN check for unsigned overflow lzxpress: add bounds checking to lzxpress decompress lzxpress: avoid technically undefined shift pidl: Add recursive depth checks utils: asn1 avoid undefined behaviour witness: idl fix length calculation for witness_IPaddrInfoList
This commit is contained in:
parent
eaa49fc4f6
commit
edc1f6e252
@ -0,0 +1,35 @@
|
||||
From 2f8c3b62266b729b47d5ba25f1966786c1af0e5f Mon Sep 17 00:00:00 2001
|
||||
From: Gary Lockyer <gary@catalyst.net.nz>
|
||||
Date: Thu, 30 Jan 2020 08:52:34 +1300
|
||||
Subject: [PATCH] idl: drsuapi_DsaAddressListItem_V1 limit recursion
|
||||
|
||||
Limit number of drsuapi_DsaAddressListItem_V1 elements to 1024
|
||||
|
||||
Credit to OSS-Fuzz
|
||||
|
||||
REF: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=19820
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14254
|
||||
|
||||
Signed-off-by: Gary Lockyer <gary@catalyst.net.nz>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
---
|
||||
librpc/idl/drsuapi.idl | 2 +-
|
||||
1 files changed, 1 insertion(+), 1 deletions(-)
|
||||
delete mode 100644 selftest/knownfail.d/bug-14254
|
||||
|
||||
diff --git a/librpc/idl/drsuapi.idl b/librpc/idl/drsuapi.idl
|
||||
index 2aaae8dce59..04725276121 100644
|
||||
--- a/librpc/idl/drsuapi.idl
|
||||
+++ b/librpc/idl/drsuapi.idl
|
||||
@@ -1452,7 +1452,7 @@ interface drsuapi
|
||||
/* list of network names of the DCs
|
||||
* to which the referral is directed */
|
||||
typedef struct {
|
||||
- drsuapi_DsaAddressListItem_V1 *next;
|
||||
+ [max_recursion(1024)] drsuapi_DsaAddressListItem_V1 *next;
|
||||
lsa_String *address;
|
||||
} drsuapi_DsaAddressListItem_V1;
|
||||
|
||||
--
|
||||
GitLab
|
||||
|
||||
126
backport-idl-limit-recurion-on-recursive-elements.patch
Normal file
126
backport-idl-limit-recurion-on-recursive-elements.patch
Normal file
@ -0,0 +1,126 @@
|
||||
From 575d39048e3b4f619d65d65303ac809c40c5d495 Mon Sep 17 00:00:00 2001
|
||||
From: Gary Lockyer <gary@catalyst.net.nz>
|
||||
Date: Fri, 7 Feb 2020 15:18:45 +1300
|
||||
Subject: [PATCH] idl: limit recurion on recursive elements
|
||||
|
||||
Limit the max_recursion on self recursive definitions in the idl to
|
||||
20,000. This value is hopefully large eneough to not impact normal
|
||||
operation, but small eneough to prevent stack over flow issues.
|
||||
|
||||
Credit to OSS-Fuzz
|
||||
|
||||
REF: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=19820
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14254
|
||||
|
||||
Signed-off-by: Gary Lockyer <gary@catalyst.net.nz>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
|
||||
Autobuild-User(master): Andrew Bartlett <abartlet@samba.org>
|
||||
Autobuild-Date(master): Thu Feb 27 02:29:21 UTC 2020 on sn-devel-184
|
||||
---
|
||||
librpc/idl/drsblobs.idl | 2 +-
|
||||
librpc/idl/drsuapi.idl | 12 ++++++++----
|
||||
librpc/idl/ioctl.idl | 2 +-
|
||||
source3/librpc/idl/secrets.idl | 2 +-
|
||||
source3/librpc/idl/smbXsrv.idl | 2 +-
|
||||
5 files changed, 12 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/librpc/idl/drsblobs.idl b/librpc/idl/drsblobs.idl
|
||||
index 072546a4369..b096b671c80 100644
|
||||
--- a/librpc/idl/drsblobs.idl
|
||||
+++ b/librpc/idl/drsblobs.idl
|
||||
@@ -579,7 +579,7 @@ interface drsblobs {
|
||||
} ExtendedErrorParam;
|
||||
|
||||
typedef [public] struct {
|
||||
- ExtendedErrorInfo *next;
|
||||
+ [max_recursion(20000)] ExtendedErrorInfo *next;
|
||||
ExtendedErrorComputerName computer_name;
|
||||
hyper pid;
|
||||
NTTIME time;
|
||||
diff --git a/librpc/idl/drsuapi.idl b/librpc/idl/drsuapi.idl
|
||||
index 04725276121..db00eb8639e 100644
|
||||
--- a/librpc/idl/drsuapi.idl
|
||||
+++ b/librpc/idl/drsuapi.idl
|
||||
@@ -690,7 +690,8 @@ interface drsuapi
|
||||
} drsuapi_DsReplicaMetaDataCtr;
|
||||
|
||||
typedef [public,noprint] struct {
|
||||
- drsuapi_DsReplicaObjectListItemEx *next_object;
|
||||
+ [max_recursion(20000)]
|
||||
+ drsuapi_DsReplicaObjectListItemEx *next_object;
|
||||
drsuapi_DsReplicaObject object;
|
||||
boolean32 is_nc_prefix;
|
||||
GUID *parent_object_guid;
|
||||
@@ -1308,7 +1309,8 @@ interface drsuapi
|
||||
/*****************/
|
||||
/* Function 0x11 */
|
||||
typedef [public,noprint] struct {
|
||||
- drsuapi_DsReplicaObjectListItem *next_object;
|
||||
+ [max_recursion(20000)]
|
||||
+ drsuapi_DsReplicaObjectListItem *next_object;
|
||||
drsuapi_DsReplicaObject object;
|
||||
} drsuapi_DsReplicaObjectListItem;
|
||||
|
||||
@@ -1408,7 +1410,8 @@ interface drsuapi
|
||||
} drsuapi_DsAddEntry_AttrErr_V1;
|
||||
|
||||
typedef [noprint] struct {
|
||||
- drsuapi_DsAddEntry_AttrErrListItem_V1 *next;
|
||||
+ [max_recursion(20000)]
|
||||
+ drsuapi_DsAddEntry_AttrErrListItem_V1 *next;
|
||||
drsuapi_DsAddEntry_AttrErr_V1 err_data;
|
||||
} drsuapi_DsAddEntry_AttrErrListItem_V1;
|
||||
|
||||
@@ -1464,7 +1467,8 @@ interface drsuapi
|
||||
drsuapi_DsAddEntry_RefType ref_type;
|
||||
uint16 addr_list_count;
|
||||
drsuapi_DsaAddressListItem_V1 *addr_list;
|
||||
- drsuapi_DsAddEntry_RefErrListItem_V1 *next;
|
||||
+ [max_recursion(20000)]
|
||||
+ drsuapi_DsAddEntry_RefErrListItem_V1 *next;
|
||||
boolean32 is_choice_set;
|
||||
drsuapi_DsAddEntry_ChoiceType choice;
|
||||
} drsuapi_DsAddEntry_RefErrListItem_V1;
|
||||
diff --git a/librpc/idl/ioctl.idl b/librpc/idl/ioctl.idl
|
||||
index ba68fbcb8f6..390e8562f69 100644
|
||||
--- a/librpc/idl/ioctl.idl
|
||||
+++ b/librpc/idl/ioctl.idl
|
||||
@@ -151,7 +151,7 @@ interface netinterface
|
||||
} fsctl_sockaddr_storage;
|
||||
|
||||
typedef [public,relative_base,noprint] struct {
|
||||
- [relative] fsctl_net_iface_info *next;
|
||||
+ [relative,max_recursion(20000)] fsctl_net_iface_info *next;
|
||||
uint32 ifindex;
|
||||
fsctl_net_iface_capability capability;
|
||||
[value(0)] uint32 reserved;
|
||||
diff --git a/source3/librpc/idl/secrets.idl b/source3/librpc/idl/secrets.idl
|
||||
index 2c06fa6990d..186d925e45e 100644
|
||||
--- a/source3/librpc/idl/secrets.idl
|
||||
+++ b/source3/librpc/idl/secrets.idl
|
||||
@@ -100,7 +100,7 @@ import "misc.idl", "samr.idl", "lsa.idl", "netlogon.idl", "security.idl";
|
||||
|
||||
NTTIME password_last_change;
|
||||
hyper password_changes;
|
||||
- secrets_domain_info1_change *next_change;
|
||||
+ [max_recursion(20000)] secrets_domain_info1_change *next_change;
|
||||
|
||||
[ref] secrets_domain_info1_password *password;
|
||||
secrets_domain_info1_password *old_password;
|
||||
diff --git a/source3/librpc/idl/smbXsrv.idl b/source3/librpc/idl/smbXsrv.idl
|
||||
index c6ce9c48789..4d9249fb3bb 100644
|
||||
--- a/source3/librpc/idl/smbXsrv.idl
|
||||
+++ b/source3/librpc/idl/smbXsrv.idl
|
||||
@@ -267,7 +267,7 @@ interface smbXsrv
|
||||
|
||||
typedef struct {
|
||||
[ignore] smbXsrv_session_auth0 *prev;
|
||||
- smbXsrv_session_auth0 *next;
|
||||
+ [max_recursion(20000)] smbXsrv_session_auth0 *next;
|
||||
[ignore] smbXsrv_session *session;
|
||||
[ignore] smbXsrv_connection *connection;
|
||||
[ignore] gensec_security *gensec;
|
||||
--
|
||||
GitLab
|
||||
|
||||
300
backport-lib-ldb-Limit-depth-of-ldb_parse_tree.patch
Normal file
300
backport-lib-ldb-Limit-depth-of-ldb_parse_tree.patch
Normal file
@ -0,0 +1,300 @@
|
||||
From a699256f438527455aaff6c73c88ee87ac7083ef Mon Sep 17 00:00:00 2001
|
||||
From: Gary Lockyer <gary@catalyst.net.nz>
|
||||
Date: Tue, 21 Apr 2020 15:37:40 +1200
|
||||
Subject: [PATCH] lib ldb: Limit depth of ldb_parse_tree
|
||||
|
||||
Limit the number of nested conditionals allowed by ldb_parse tree to
|
||||
128, to avoid potential stack overflow issues.
|
||||
|
||||
Credit Oss-Fuzz
|
||||
|
||||
REF: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=19508
|
||||
|
||||
Signed-off-by: Gary Lockyer <gary@catalyst.net.nz>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
|
||||
Autobuild-User(master): Gary Lockyer <gary@samba.org>
|
||||
Autobuild-Date(master): Sun May 10 23:21:08 UTC 2020 on sn-devel-184
|
||||
---
|
||||
lib/ldb/common/ldb_parse.c | 72 +++++++++++++++++++++++------
|
||||
lib/ldb/tests/ldb_parse_test.c | 83 +++++++++++++++++++++++++++++++++-
|
||||
2 files changed, 140 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/lib/ldb/common/ldb_parse.c b/lib/ldb/common/ldb_parse.c
|
||||
index 452c5830ed5..7e15206b168 100644
|
||||
--- a/lib/ldb/common/ldb_parse.c
|
||||
+++ b/lib/ldb/common/ldb_parse.c
|
||||
@@ -43,6 +43,16 @@
|
||||
#include "ldb_private.h"
|
||||
#include "system/locale.h"
|
||||
|
||||
+/*
|
||||
+ * Maximum depth of the filter parse tree, the value chosen is small enough to
|
||||
+ * avoid triggering ASAN stack overflow checks. But large enough to be useful.
|
||||
+ *
|
||||
+ * On Windows clients the maximum number of levels of recursion allowed is 100.
|
||||
+ * In the LDAP server, Windows restricts clients to 512 nested
|
||||
+ * (eg) OR statements.
|
||||
+ */
|
||||
+#define LDB_MAX_PARSE_TREE_DEPTH 128
|
||||
+
|
||||
static int ldb_parse_hex2char(const char *x)
|
||||
{
|
||||
if (isxdigit(x[0]) && isxdigit(x[1])) {
|
||||
@@ -231,7 +241,11 @@ static struct ldb_val **ldb_wildcard_decode(TALLOC_CTX *mem_ctx, const char *str
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static struct ldb_parse_tree *ldb_parse_filter(TALLOC_CTX *mem_ctx, const char **s);
|
||||
+static struct ldb_parse_tree *ldb_parse_filter(
|
||||
+ TALLOC_CTX *mem_ctx,
|
||||
+ const char **s,
|
||||
+ unsigned depth,
|
||||
+ unsigned max_depth);
|
||||
|
||||
|
||||
/*
|
||||
@@ -498,7 +512,11 @@ static struct ldb_parse_tree *ldb_parse_simple(TALLOC_CTX *mem_ctx, const char *
|
||||
<or> ::= '|' <filterlist>
|
||||
<filterlist> ::= <filter> | <filter> <filterlist>
|
||||
*/
|
||||
-static struct ldb_parse_tree *ldb_parse_filterlist(TALLOC_CTX *mem_ctx, const char **s)
|
||||
+static struct ldb_parse_tree *ldb_parse_filterlist(
|
||||
+ TALLOC_CTX *mem_ctx,
|
||||
+ const char **s,
|
||||
+ unsigned depth,
|
||||
+ unsigned max_depth)
|
||||
{
|
||||
struct ldb_parse_tree *ret, *next;
|
||||
enum ldb_parse_op op;
|
||||
@@ -533,7 +551,8 @@ static struct ldb_parse_tree *ldb_parse_filterlist(TALLOC_CTX *mem_ctx, const ch
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- ret->u.list.elements[0] = ldb_parse_filter(ret->u.list.elements, &p);
|
||||
+ ret->u.list.elements[0] =
|
||||
+ ldb_parse_filter(ret->u.list.elements, &p, depth, max_depth);
|
||||
if (!ret->u.list.elements[0]) {
|
||||
talloc_free(ret);
|
||||
return NULL;
|
||||
@@ -547,7 +566,8 @@ static struct ldb_parse_tree *ldb_parse_filterlist(TALLOC_CTX *mem_ctx, const ch
|
||||
break;
|
||||
}
|
||||
|
||||
- next = ldb_parse_filter(ret->u.list.elements, &p);
|
||||
+ next = ldb_parse_filter(
|
||||
+ ret->u.list.elements, &p, depth, max_depth);
|
||||
if (next == NULL) {
|
||||
/* an invalid filter element */
|
||||
talloc_free(ret);
|
||||
@@ -576,7 +596,11 @@ static struct ldb_parse_tree *ldb_parse_filterlist(TALLOC_CTX *mem_ctx, const ch
|
||||
/*
|
||||
<not> ::= '!' <filter>
|
||||
*/
|
||||
-static struct ldb_parse_tree *ldb_parse_not(TALLOC_CTX *mem_ctx, const char **s)
|
||||
+static struct ldb_parse_tree *ldb_parse_not(
|
||||
+ TALLOC_CTX *mem_ctx,
|
||||
+ const char **s,
|
||||
+ unsigned depth,
|
||||
+ unsigned max_depth)
|
||||
{
|
||||
struct ldb_parse_tree *ret;
|
||||
const char *p = *s;
|
||||
@@ -593,7 +617,7 @@ static struct ldb_parse_tree *ldb_parse_not(TALLOC_CTX *mem_ctx, const char **s)
|
||||
}
|
||||
|
||||
ret->operation = LDB_OP_NOT;
|
||||
- ret->u.isnot.child = ldb_parse_filter(ret, &p);
|
||||
+ ret->u.isnot.child = ldb_parse_filter(ret, &p, depth, max_depth);
|
||||
if (!ret->u.isnot.child) {
|
||||
talloc_free(ret);
|
||||
return NULL;
|
||||
@@ -608,7 +632,11 @@ static struct ldb_parse_tree *ldb_parse_not(TALLOC_CTX *mem_ctx, const char **s)
|
||||
parse a filtercomp
|
||||
<filtercomp> ::= <and> | <or> | <not> | <simple>
|
||||
*/
|
||||
-static struct ldb_parse_tree *ldb_parse_filtercomp(TALLOC_CTX *mem_ctx, const char **s)
|
||||
+static struct ldb_parse_tree *ldb_parse_filtercomp(
|
||||
+ TALLOC_CTX *mem_ctx,
|
||||
+ const char **s,
|
||||
+ unsigned depth,
|
||||
+ unsigned max_depth)
|
||||
{
|
||||
struct ldb_parse_tree *ret;
|
||||
const char *p = *s;
|
||||
@@ -617,15 +645,15 @@ static struct ldb_parse_tree *ldb_parse_filtercomp(TALLOC_CTX *mem_ctx, const ch
|
||||
|
||||
switch (*p) {
|
||||
case '&':
|
||||
- ret = ldb_parse_filterlist(mem_ctx, &p);
|
||||
+ ret = ldb_parse_filterlist(mem_ctx, &p, depth, max_depth);
|
||||
break;
|
||||
|
||||
case '|':
|
||||
- ret = ldb_parse_filterlist(mem_ctx, &p);
|
||||
+ ret = ldb_parse_filterlist(mem_ctx, &p, depth, max_depth);
|
||||
break;
|
||||
|
||||
case '!':
|
||||
- ret = ldb_parse_not(mem_ctx, &p);
|
||||
+ ret = ldb_parse_not(mem_ctx, &p, depth, max_depth);
|
||||
break;
|
||||
|
||||
case '(':
|
||||
@@ -641,21 +669,34 @@ static struct ldb_parse_tree *ldb_parse_filtercomp(TALLOC_CTX *mem_ctx, const ch
|
||||
return ret;
|
||||
}
|
||||
|
||||
-
|
||||
/*
|
||||
<filter> ::= '(' <filtercomp> ')'
|
||||
*/
|
||||
-static struct ldb_parse_tree *ldb_parse_filter(TALLOC_CTX *mem_ctx, const char **s)
|
||||
+static struct ldb_parse_tree *ldb_parse_filter(
|
||||
+ TALLOC_CTX *mem_ctx,
|
||||
+ const char **s,
|
||||
+ unsigned depth,
|
||||
+ unsigned max_depth)
|
||||
{
|
||||
struct ldb_parse_tree *ret;
|
||||
const char *p = *s;
|
||||
|
||||
+ /*
|
||||
+ * Check the depth of the parse tree, and reject the input if
|
||||
+ * max_depth exceeded. This avoids stack overflow
|
||||
+ * issues.
|
||||
+ */
|
||||
+ if (depth > max_depth) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ depth++;
|
||||
+
|
||||
if (*p != '(') {
|
||||
return NULL;
|
||||
}
|
||||
p++;
|
||||
|
||||
- ret = ldb_parse_filtercomp(mem_ctx, &p);
|
||||
+ ret = ldb_parse_filtercomp(mem_ctx, &p, depth, max_depth);
|
||||
|
||||
if (*p != ')') {
|
||||
return NULL;
|
||||
@@ -679,6 +720,8 @@ static struct ldb_parse_tree *ldb_parse_filter(TALLOC_CTX *mem_ctx, const char *
|
||||
*/
|
||||
struct ldb_parse_tree *ldb_parse_tree(TALLOC_CTX *mem_ctx, const char *s)
|
||||
{
|
||||
+ unsigned depth = 0;
|
||||
+
|
||||
while (s && isspace((unsigned char)*s)) s++;
|
||||
|
||||
if (s == NULL || *s == 0) {
|
||||
@@ -686,7 +729,8 @@ struct ldb_parse_tree *ldb_parse_tree(TALLOC_CTX *mem_ctx, const char *s)
|
||||
}
|
||||
|
||||
if (*s == '(') {
|
||||
- return ldb_parse_filter(mem_ctx, &s);
|
||||
+ return ldb_parse_filter(
|
||||
+ mem_ctx, &s, depth, LDB_MAX_PARSE_TREE_DEPTH);
|
||||
}
|
||||
|
||||
return ldb_parse_simple(mem_ctx, &s);
|
||||
diff --git a/lib/ldb/tests/ldb_parse_test.c b/lib/ldb/tests/ldb_parse_test.c
|
||||
index a739d7795d1..d7442b954ea 100644
|
||||
--- a/lib/ldb/tests/ldb_parse_test.c
|
||||
+++ b/lib/ldb/tests/ldb_parse_test.c
|
||||
@@ -81,10 +81,91 @@ static void test_parse_filtertype(void **state)
|
||||
test_roundtrip(ctx, " ", "(|(objectClass=*)(distinguishedName=*))");
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Test that a nested query with 128 levels of nesting is accepted
|
||||
+ */
|
||||
+static void test_nested_filter_eq_limit(void **state)
|
||||
+{
|
||||
+ struct test_ctx *ctx =
|
||||
+ talloc_get_type_abort(*state, struct test_ctx);
|
||||
+
|
||||
+ /*
|
||||
+ * 128 nested clauses
|
||||
+ */
|
||||
+ const char *nested_query = ""
|
||||
+ "(|(!(|(&(|(|(|(|(|(|(|(|(|(|(|(|"
|
||||
+ "(|(!(|(&(|(|(|(|(|(|(!(|(!(|(|(|"
|
||||
+ "(|(!(|(&(|(|(&(|(|(|(|(|(!(!(!(|"
|
||||
+ "(|(!(|(&(|(|(|(|(|(|(|(|(|(|(|(|"
|
||||
+ "(|(!(|(&(|(|(|(!(|(|(&(|(|(|(|(|"
|
||||
+ "(|(!(|(&(|(|(&(|(|(|(|(|(&(&(|(|"
|
||||
+ "(|(!(|(&(|(|(|(|(|(|(!(|(|(|(|(|"
|
||||
+ "(|(!(|(&(|(|(!(|(|(|(|(|(|(|(|(|"
|
||||
+ "(a=b)"
|
||||
+ "))))))))))))))))"
|
||||
+ "))))))))))))))))"
|
||||
+ "))))))))))))))))"
|
||||
+ "))))))))))))))))"
|
||||
+ "))))))))))))))))"
|
||||
+ "))))))))))))))))"
|
||||
+ "))))))))))))))))"
|
||||
+ "))))))))))))))))";
|
||||
+
|
||||
+ struct ldb_parse_tree *tree = ldb_parse_tree(ctx, nested_query);
|
||||
+
|
||||
+ assert_non_null(tree);
|
||||
+ /*
|
||||
+ * Check that we get the same query back
|
||||
+ */
|
||||
+ test_roundtrip(ctx, nested_query, nested_query);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Test that a nested query with 129 levels of nesting is rejected.
|
||||
+ */
|
||||
+static void test_nested_filter_gt_limit(void **state)
|
||||
+{
|
||||
+ struct test_ctx *ctx =
|
||||
+ talloc_get_type_abort(*state, struct test_ctx);
|
||||
+
|
||||
+ /*
|
||||
+ * 129 nested clauses
|
||||
+ */
|
||||
+ const char *nested_query = ""
|
||||
+ "(|(!(|(|(&(|(|(|(|(&(|(|(|(|(|(|"
|
||||
+ "(|(!(|(|(&(|(|(|(|(|(|(|(|(|(|(|"
|
||||
+ "(|(!(|(|(&(|(|(!(|(|(|(|(!(|(|(|"
|
||||
+ "(|(!(|(|(&(|(|(|(|(|(|(|(|(|(|(|"
|
||||
+ "(|(!(|(|(&(|(|(|(!(&(|(|(|(|(|(|"
|
||||
+ "(|(!(|(|(&(|(|(|(|(|(|(|(|(|(|(|"
|
||||
+ "(|(!(|(|(&(|(|(|(|(|(|(|(|(|(|(|"
|
||||
+ "(|(!(|(|(&(|(|(|(|(|(|(|(|(&(|(|"
|
||||
+ "(|"
|
||||
+ "(a=b)"
|
||||
+ ")"
|
||||
+ "))))))))))))))))"
|
||||
+ "))))))))))))))))"
|
||||
+ "))))))))))))))))"
|
||||
+ "))))))))))))))))"
|
||||
+ "))))))))))))))))"
|
||||
+ "))))))))))))))))"
|
||||
+ "))))))))))))))))"
|
||||
+ "))))))))))))))))";
|
||||
+
|
||||
+ struct ldb_parse_tree *tree = ldb_parse_tree(ctx, nested_query);
|
||||
+
|
||||
+ assert_null(tree);
|
||||
+}
|
||||
+
|
||||
int main(int argc, const char **argv)
|
||||
{
|
||||
const struct CMUnitTest tests[] = {
|
||||
- cmocka_unit_test_setup_teardown(test_parse_filtertype, setup, teardown),
|
||||
+ cmocka_unit_test_setup_teardown(
|
||||
+ test_parse_filtertype, setup, teardown),
|
||||
+ cmocka_unit_test_setup_teardown(
|
||||
+ test_nested_filter_eq_limit, setup, teardown),
|
||||
+ cmocka_unit_test_setup_teardown(
|
||||
+ test_nested_filter_gt_limit, setup, teardown),
|
||||
};
|
||||
|
||||
cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
|
||||
--
|
||||
GitLab
|
||||
|
||||
@ -0,0 +1,208 @@
|
||||
From ae6927e4f08dcea89729d8e54363e98effab6624 Mon Sep 17 00:00:00 2001
|
||||
From: Gary Lockyer <gary@catalyst.net.nz>
|
||||
Date: Fri, 24 Jan 2020 10:41:35 +1300
|
||||
Subject: [PATCH] librpc ndr: Heap-buffer-overflow in lzxpress_decompress
|
||||
|
||||
Reproducer for oss-fuzz Issue 20083
|
||||
|
||||
Project: samba
|
||||
Fuzzing Engine: libFuzzer
|
||||
Fuzz Target: fuzz_ndr_drsuapi_TYPE_OUT
|
||||
Job Type: libfuzzer_asan_samba
|
||||
Platform Id: linux
|
||||
|
||||
Crash Type: Heap-buffer-overflow READ 1
|
||||
Crash Address: 0x6040000002fd
|
||||
Crash State:
|
||||
lzxpress_decompress
|
||||
ndr_pull_compression_xpress_chunk
|
||||
ndr_pull_compression_start
|
||||
|
||||
Sanitizer: address (ASAN)
|
||||
|
||||
Recommended Security Severity: Medium
|
||||
|
||||
Credit to OSS-Fuzz
|
||||
|
||||
REF: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=20083
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14236
|
||||
|
||||
Signed-off-by: Gary Lockyer <gary@catalyst.net.nz>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
---
|
||||
librpc/ndr/libndr.h | 5 +-
|
||||
librpc/tests/test_ndr.c | 84 ++++++++++++++++++++++++++
|
||||
librpc/wscript_build | 8 +++
|
||||
python/samba/tests/blackbox/ndrdump.py | 13 ++++
|
||||
selftest/knownfail.d/bug-14236 | 1 +
|
||||
source4/selftest/tests.py | 2 +
|
||||
6 files changed, 112 insertions(+), 1 deletion(-)
|
||||
create mode 100644 librpc/tests/test_ndr.c
|
||||
create mode 100644 selftest/knownfail.d/bug-14236
|
||||
|
||||
diff --git a/librpc/ndr/libndr.h b/librpc/ndr/libndr.h
|
||||
index 58ef517d363..b7cccf3dfc5 100644
|
||||
--- a/librpc/ndr/libndr.h
|
||||
+++ b/librpc/ndr/libndr.h
|
||||
@@ -309,7 +309,10 @@ enum ndr_compression_alg {
|
||||
} while (0)
|
||||
|
||||
#define NDR_PULL_NEED_BYTES(ndr, n) do { \
|
||||
- if (unlikely((n) > ndr->data_size || ndr->offset + (n) > ndr->data_size)) { \
|
||||
+ if (unlikely(\
|
||||
+ (n) > ndr->data_size || \
|
||||
+ ndr->offset + (n) > ndr->data_size || \
|
||||
+ ndr->offset + (n) < ndr->offset)) { \
|
||||
if (ndr->flags & LIBNDR_FLAG_INCOMPLETE_BUFFER) { \
|
||||
uint32_t _available = ndr->data_size - ndr->offset; \
|
||||
uint32_t _missing = n - _available; \
|
||||
diff --git a/librpc/tests/test_ndr.c b/librpc/tests/test_ndr.c
|
||||
new file mode 100644
|
||||
index 00000000000..1c074d71023
|
||||
--- /dev/null
|
||||
+++ b/librpc/tests/test_ndr.c
|
||||
@@ -0,0 +1,84 @@
|
||||
+/*
|
||||
+ * Tests for librpc ndr functions
|
||||
+ *
|
||||
+ * Copyright (C) Catalyst.NET Ltd 2020
|
||||
+ *
|
||||
+ * 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/>.
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+/*
|
||||
+ * from cmocka.c:
|
||||
+ * These headers or their equivalents should be included prior to
|
||||
+ * including
|
||||
+ * this header file.
|
||||
+ *
|
||||
+ * #include <stdarg.h>
|
||||
+ * #include <stddef.h>
|
||||
+ * #include <setjmp.h>
|
||||
+ *
|
||||
+ * This allows test applications to use custom definitions of C standard
|
||||
+ * library functions and types.
|
||||
+ *
|
||||
+ */
|
||||
+#include <stdarg.h>
|
||||
+#include <stddef.h>
|
||||
+#include <stdint.h>
|
||||
+#include <setjmp.h>
|
||||
+#include <cmocka.h>
|
||||
+
|
||||
+#include "librpc/ndr/libndr.h"
|
||||
+
|
||||
+/*
|
||||
+ * Test NDR_PULL_NEED_BYTES integer overflow handling.
|
||||
+ */
|
||||
+static enum ndr_err_code wrap_NDR_PULL_NEED_BYTES(
|
||||
+ struct ndr_pull *ndr,
|
||||
+ uint32_t bytes) {
|
||||
+
|
||||
+ NDR_PULL_NEED_BYTES(ndr, bytes);
|
||||
+ return NDR_ERR_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+static void test_NDR_PULL_NEED_BYTES(void **state)
|
||||
+{
|
||||
+ struct ndr_pull ndr = {0};
|
||||
+ enum ndr_err_code err;
|
||||
+
|
||||
+ ndr.data_size = UINT32_MAX;
|
||||
+ ndr.offset = UINT32_MAX -1;
|
||||
+
|
||||
+ /*
|
||||
+ * This will not cause an overflow
|
||||
+ */
|
||||
+ err = wrap_NDR_PULL_NEED_BYTES(&ndr, 1);
|
||||
+ assert_int_equal(NDR_ERR_SUCCESS, err);
|
||||
+
|
||||
+ /*
|
||||
+ * This will cause an overflow
|
||||
+ * and (offset + n) will be less than data_size
|
||||
+ */
|
||||
+ err = wrap_NDR_PULL_NEED_BYTES(&ndr, 2);
|
||||
+ assert_int_equal(NDR_ERR_BUFSIZE, err);
|
||||
+}
|
||||
+
|
||||
+int main(int argc, const char **argv)
|
||||
+{
|
||||
+ const struct CMUnitTest tests[] = {
|
||||
+ cmocka_unit_test(test_NDR_PULL_NEED_BYTES),
|
||||
+ };
|
||||
+
|
||||
+ cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
|
||||
+ return cmocka_run_group_tests(tests, NULL, NULL);
|
||||
+}
|
||||
diff --git a/librpc/wscript_build b/librpc/wscript_build
|
||||
index 5eb78e6010a8..ec8697fbcc58 100644
|
||||
--- a/librpc/wscript_build
|
||||
+++ b/librpc/wscript_build
|
||||
@@ -698,3 +698,11 @@ bld.SAMBA_BINARY('test_ndr_string',
|
||||
ndr_nbt
|
||||
''',
|
||||
for_selftest=True)
|
||||
+
|
||||
+bld.SAMBA_BINARY('test_ndr',
|
||||
+ source='tests/test_ndr.c',
|
||||
+ deps='''
|
||||
+ cmocka
|
||||
+ ndr
|
||||
+ ''',
|
||||
+ for_selftest=True)
|
||||
diff --git a/python/samba/tests/blackbox/ndrdump.py b/python/samba/tests/blackbox/ndrdump.py
|
||||
index b3c837819b15..205519c3f8a6 100644
|
||||
--- a/python/samba/tests/blackbox/ndrdump.py
|
||||
+++ b/python/samba/tests/blackbox/ndrdump.py
|
||||
@@ -437,3 +437,16 @@ def test_fuzzed_drsuapi_DsGetNCChanges(self):
|
||||
except BlackboxProcessError as e:
|
||||
self.fail(e)
|
||||
self.assertEqual(actual, expected)
|
||||
+
|
||||
+ def test_ndrdump_fuzzed_ndr_compression(self):
|
||||
+ expected = 'pull returned Buffer Size Error'
|
||||
+ command = (
|
||||
+ "ndrdump drsuapi 3 out --base64-input "
|
||||
+ "--input BwAAAAcAAAAGAAAAAwAgICAgICAJAAAAICAgIAkAAAAgIAAA//////8=")
|
||||
+ try:
|
||||
+ actual = self.check_exit_code(command, 2)
|
||||
+ except BlackboxProcessError as e:
|
||||
+ self.fail(e)
|
||||
+ # check_output will return bytes
|
||||
+ # convert expected to bytes for python 3
|
||||
+ self.assertRegex(actual.decode('utf8'), expected + '$')
|
||||
diff --git a/selftest/knownfail.d/bug-14236 b/selftest/knownfail.d/bug-14236
|
||||
new file mode 100644
|
||||
index 00000000000..64b956997a6
|
||||
--- /dev/null
|
||||
+++ b/selftest/knownfail.d/bug-14236
|
||||
@@ -0,0 +1 @@
|
||||
+^samba.tests.blackbox.ndrdump.samba.tests.blackbox.ndrdump.NdrDumpTests.test_ndrdump_fuzzed_ndr_compression
|
||||
diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py
|
||||
index f570d35dfba..ab2c4f69da0 100755
|
||||
--- a/source4/selftest/tests.py
|
||||
+++ b/source4/selftest/tests.py
|
||||
@@ -1334,6 +1334,8 @@ plantestsuite("libcli.drsuapi.repl_decrypt", "none",
|
||||
[os.path.join(bindir(), "test_ldap_message")])
|
||||
plantestsuite("librpc.ndr.ndr_macros", "none",
|
||||
[os.path.join(bindir(), "test_ndr_macros")])
|
||||
+plantestsuite("librpc.ndr.ndr", "none",
|
||||
+ [os.path.join(bindir(), "test_ndr")])
|
||||
|
||||
# process restart and limit tests, these break the environment so need to run
|
||||
# in their own specific environment
|
||||
--
|
||||
GitLab
|
||||
|
||||
@ -0,0 +1,40 @@
|
||||
From 6d05fb3ea772c3642624ec6e0fb4e8d099bcdb8e Mon Sep 17 00:00:00 2001
|
||||
From: Gary Lockyer <gary@catalyst.net.nz>
|
||||
Date: Wed, 22 Jan 2020 14:16:02 +1300
|
||||
Subject: [PATCH] librpc ndr: NDR_PULL_ALIGN check for unsigned overflow
|
||||
|
||||
Handle uint32 overflow in NDR_PULL_ALIGN
|
||||
|
||||
Credit to OSS-Fuzz
|
||||
|
||||
REF: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=20083
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14236
|
||||
|
||||
Signed-off-by: Gary Lockyer <gary@catalyst.net.nz>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
---
|
||||
librpc/ndr/libndr.h | 7 +++++++
|
||||
selftest/knownfail.d/bug-14236 | 1 -
|
||||
2 files changed, 7 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/librpc/ndr/libndr.h b/librpc/ndr/libndr.h
|
||||
index b7cccf3dfc5..c2c7e263049 100644
|
||||
--- a/librpc/ndr/libndr.h
|
||||
+++ b/librpc/ndr/libndr.h
|
||||
@@ -331,6 +331,13 @@ enum ndr_compression_alg {
|
||||
if (unlikely(ndr->flags & LIBNDR_FLAG_PAD_CHECK)) { \
|
||||
ndr_check_padding(ndr, n); \
|
||||
} \
|
||||
+ if(unlikely( \
|
||||
+ ((ndr->offset + (n-1)) & (~(n-1))) < ndr->offset)) {\
|
||||
+ return ndr_pull_error( \
|
||||
+ ndr, \
|
||||
+ NDR_ERR_BUFSIZE, \
|
||||
+ "Pull align (overflow) %u", (unsigned)n); \
|
||||
+ } \
|
||||
ndr->offset = (ndr->offset + (n-1)) & ~(n-1); \
|
||||
} \
|
||||
if (unlikely(ndr->offset > ndr->data_size)) { \
|
||||
--
|
||||
GitLab
|
||||
|
||||
277
backport-librpc-ndr-add-recursion-check-macros.patch
Normal file
277
backport-librpc-ndr-add-recursion-check-macros.patch
Normal file
@ -0,0 +1,277 @@
|
||||
From ba518a1debbe2dd8231ba2fb9bbb07eef743d86f Mon Sep 17 00:00:00 2001
|
||||
From: Gary Lockyer <gary@catalyst.net.nz>
|
||||
Date: Thu, 30 Jan 2020 08:49:07 +1300
|
||||
Subject: [PATCH] librpc ndr: add recursion check macros
|
||||
|
||||
Add macros to check the recursion depth.
|
||||
|
||||
Credit to OSS-Fuzz
|
||||
|
||||
REF: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=19280
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14254
|
||||
|
||||
Signed-off-by: Gary Lockyer <gary@catalyst.net.nz>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
---
|
||||
librpc/ndr/libndr.h | 37 ++++++++-
|
||||
librpc/ndr/ndr.c | 2 +
|
||||
librpc/tests/test_ndr_macros.c | 138 +++++++++++++++++++++++++++++++++
|
||||
librpc/wscript_build | 9 +++
|
||||
source4/selftest/tests.py | 2 +
|
||||
5 files changed, 187 insertions(+), 1 deletion(-)
|
||||
create mode 100644 librpc/tests/test_ndr_macros.c
|
||||
|
||||
diff --git a/librpc/ndr/libndr.h b/librpc/ndr/libndr.h
|
||||
index 8d407c40e43..fd87db928ed 100644
|
||||
--- a/librpc/ndr/libndr.h
|
||||
+++ b/librpc/ndr/libndr.h
|
||||
@@ -79,6 +79,14 @@ struct ndr_pull {
|
||||
/* this is used to ensure we generate unique reference IDs
|
||||
between request and reply */
|
||||
uint32_t ptr_count;
|
||||
+ uint32_t recursion_depth;
|
||||
+ /*
|
||||
+ * The global maximum depth for recursion. When set it overrides the
|
||||
+ * value supplied by the max_recursion idl attribute. This is needed
|
||||
+ * for fuzzing as ASAN uses a low threshold for stack depth to check
|
||||
+ * for stack overflow.
|
||||
+ */
|
||||
+ uint32_t global_max_recursion;
|
||||
};
|
||||
|
||||
/* structure passed to functions that generate NDR formatted data */
|
||||
@@ -249,7 +257,9 @@ enum ndr_err_code {
|
||||
NDR_ERR_UNREAD_BYTES,
|
||||
NDR_ERR_NDR64,
|
||||
NDR_ERR_FLAGS,
|
||||
- NDR_ERR_INCOMPLETE_BUFFER
|
||||
+ NDR_ERR_INCOMPLETE_BUFFER,
|
||||
+ NDR_ERR_MAX_RECURSION_EXCEEDED,
|
||||
+ NDR_ERR_UNDERFLOW
|
||||
};
|
||||
|
||||
#define NDR_ERR_CODE_IS_SUCCESS(x) (x == NDR_ERR_SUCCESS)
|
||||
@@ -357,6 +367,31 @@ enum ndr_compression_alg {
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
+#define NDR_RECURSION_CHECK(ndr, d) do { \
|
||||
+ uint32_t _ndr_min_ = (d); \
|
||||
+ if (ndr->global_max_recursion && ndr->global_max_recursion < (d)) { \
|
||||
+ _ndr_min_ = ndr->global_max_recursion; \
|
||||
+ } \
|
||||
+ ndr->recursion_depth++; \
|
||||
+ if (unlikely(ndr->recursion_depth > _ndr_min_)) { \
|
||||
+ return ndr_pull_error( \
|
||||
+ ndr, \
|
||||
+ NDR_ERR_MAX_RECURSION_EXCEEDED, \
|
||||
+ "Depth of recursion exceeds (%u)", \
|
||||
+ (unsigned) d); \
|
||||
+ } \
|
||||
+} while (0)
|
||||
+
|
||||
+#define NDR_RECURSION_UNWIND(ndr) do { \
|
||||
+ if (unlikely(ndr->recursion_depth == 0)) { \
|
||||
+ return ndr_pull_error( \
|
||||
+ ndr, \
|
||||
+ NDR_ERR_UNDERFLOW, \
|
||||
+ "ndr_pull.recursion_depth is 0"); \
|
||||
+ } \
|
||||
+ ndr->recursion_depth--; \
|
||||
+} while (0)
|
||||
+
|
||||
/* these are used to make the error checking on each element in libndr
|
||||
less tedious, hopefully making the code more readable */
|
||||
#define NDR_CHECK(call) do { \
|
||||
diff --git a/librpc/ndr/ndr.c b/librpc/ndr/ndr.c
|
||||
index f96a0bca08b..afe22a28602 100644
|
||||
--- a/librpc/ndr/ndr.c
|
||||
+++ b/librpc/ndr/ndr.c
|
||||
@@ -1950,6 +1950,8 @@ static const struct {
|
||||
{ NDR_ERR_UNREAD_BYTES, "Unread Bytes" },
|
||||
{ NDR_ERR_NDR64, "NDR64 assertion error" },
|
||||
{ NDR_ERR_INCOMPLETE_BUFFER, "Incomplete Buffer" },
|
||||
+ { NDR_ERR_MAX_RECURSION_EXCEEDED, "Maximum Recursion Exceeded" },
|
||||
+ { NDR_ERR_UNDERFLOW, "Underflow" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
diff --git a/librpc/tests/test_ndr_macros.c b/librpc/tests/test_ndr_macros.c
|
||||
new file mode 100644
|
||||
index 00000000000..0cd20d3e8f3
|
||||
--- /dev/null
|
||||
+++ b/librpc/tests/test_ndr_macros.c
|
||||
@@ -0,0 +1,138 @@
|
||||
+/*
|
||||
+ * Tests for librpc ndr functions
|
||||
+ *
|
||||
+ * Copyright (C) Catalyst.NET Ltd 2020
|
||||
+ *
|
||||
+ * 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/>.
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+/*
|
||||
+ * from cmocka.c:
|
||||
+ * These headers or their equivalents should be included prior to
|
||||
+ * including
|
||||
+ * this header file.
|
||||
+ *
|
||||
+ * #include <stdarg.h>
|
||||
+ * #include <stddef.h>
|
||||
+ * #include <setjmp.h>
|
||||
+ *
|
||||
+ * This allows test applications to use custom definitions of C standard
|
||||
+ * library functions and types.
|
||||
+ *
|
||||
+ */
|
||||
+#include <stdarg.h>
|
||||
+#include <stddef.h>
|
||||
+#include <stdint.h>
|
||||
+#include <setjmp.h>
|
||||
+#include <cmocka.h>
|
||||
+
|
||||
+#include "librpc/ndr/libndr.h"
|
||||
+
|
||||
+/*
|
||||
+ * Test NDR_RECURSION_CHECK.
|
||||
+ */
|
||||
+static enum ndr_err_code wrap_NDR_RECURSION_CHECK(
|
||||
+ struct ndr_pull *ndr,
|
||||
+ uint32_t bytes) {
|
||||
+
|
||||
+ NDR_RECURSION_CHECK(ndr, bytes);
|
||||
+ return NDR_ERR_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+static void test_NDR_RECURSION_CHECK(void **state)
|
||||
+{
|
||||
+ struct ndr_pull ndr = {0};
|
||||
+ enum ndr_err_code err;
|
||||
+
|
||||
+
|
||||
+ ndr.global_max_recursion = 0;
|
||||
+ ndr.recursion_depth = 42;
|
||||
+ err = wrap_NDR_RECURSION_CHECK(&ndr, 43);
|
||||
+ assert_int_equal(NDR_ERR_SUCCESS, err);
|
||||
+ assert_int_equal(43, ndr.recursion_depth);
|
||||
+
|
||||
+ ndr.global_max_recursion = 0;
|
||||
+ ndr.recursion_depth = 43;
|
||||
+ err = wrap_NDR_RECURSION_CHECK(&ndr, 43);
|
||||
+ assert_int_equal(NDR_ERR_MAX_RECURSION_EXCEEDED, err);
|
||||
+ assert_int_equal(44, ndr.recursion_depth);
|
||||
+
|
||||
+ ndr.global_max_recursion = 0;
|
||||
+ ndr.recursion_depth = 44;
|
||||
+ err = wrap_NDR_RECURSION_CHECK(&ndr, 43);
|
||||
+ assert_int_equal(NDR_ERR_MAX_RECURSION_EXCEEDED, err);
|
||||
+ assert_int_equal(45, ndr.recursion_depth);
|
||||
+
|
||||
+ ndr.global_max_recursion = 5;
|
||||
+ ndr.recursion_depth = 5;
|
||||
+ err = wrap_NDR_RECURSION_CHECK(&ndr, 20);
|
||||
+ assert_int_equal(NDR_ERR_MAX_RECURSION_EXCEEDED, err);
|
||||
+ assert_int_equal(6, ndr.recursion_depth);
|
||||
+
|
||||
+ ndr.global_max_recursion = 5;
|
||||
+ ndr.recursion_depth = 4;
|
||||
+ err = wrap_NDR_RECURSION_CHECK(&ndr, 20);
|
||||
+ assert_int_equal(NDR_ERR_SUCCESS, err);
|
||||
+ assert_int_equal(5, ndr.recursion_depth);
|
||||
+
|
||||
+ ndr.global_max_recursion = 20;
|
||||
+ ndr.recursion_depth = 5;
|
||||
+ err = wrap_NDR_RECURSION_CHECK(&ndr, 5);
|
||||
+ assert_int_equal(NDR_ERR_MAX_RECURSION_EXCEEDED, err);
|
||||
+ assert_int_equal(6, ndr.recursion_depth);
|
||||
+
|
||||
+ ndr.global_max_recursion = 20;
|
||||
+ ndr.recursion_depth = 4;
|
||||
+ err = wrap_NDR_RECURSION_CHECK(&ndr, 5);
|
||||
+ assert_int_equal(NDR_ERR_SUCCESS, err);
|
||||
+ assert_int_equal(5, ndr.recursion_depth);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Test NDR_RECURSION_RETURN.
|
||||
+ */
|
||||
+static enum ndr_err_code wrap_NDR_RECURSION_UNWIND(
|
||||
+ struct ndr_pull *ndr) {
|
||||
+
|
||||
+ NDR_RECURSION_UNWIND(ndr);
|
||||
+ return NDR_ERR_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+static void test_NDR_RECURSION_UNWIND(void **state)
|
||||
+{
|
||||
+ struct ndr_pull ndr = {0};
|
||||
+ enum ndr_err_code err;
|
||||
+
|
||||
+ ndr.recursion_depth = 5;
|
||||
+ err = wrap_NDR_RECURSION_UNWIND(&ndr);
|
||||
+ assert_int_equal(NDR_ERR_SUCCESS, err);
|
||||
+ assert_int_equal(4, ndr.recursion_depth);
|
||||
+
|
||||
+ ndr.recursion_depth = 0;
|
||||
+ err = wrap_NDR_RECURSION_UNWIND(&ndr);
|
||||
+ assert_int_equal(NDR_ERR_UNDERFLOW, err);
|
||||
+ assert_int_equal(0, ndr.recursion_depth);
|
||||
+
|
||||
+}
|
||||
+int main(int argc, const char **argv)
|
||||
+{
|
||||
+ const struct CMUnitTest tests[] = {
|
||||
+ cmocka_unit_test(test_NDR_RECURSION_CHECK),
|
||||
+ cmocka_unit_test(test_NDR_RECURSION_UNWIND),
|
||||
+ };
|
||||
+
|
||||
+ cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
|
||||
+ return cmocka_run_group_tests(tests, NULL, NULL);
|
||||
+}
|
||||
diff --git a/librpc/wscript_build b/librpc/wscript_build
|
||||
index ec8697fbcc5..f0bf7f7785e 100644
|
||||
--- a/librpc/wscript_build
|
||||
+++ b/librpc/wscript_build
|
||||
@@ -690,6 +690,14 @@ bld.SAMBA_SUBSYSTEM('NDR_FSRVP_STATE',
|
||||
#
|
||||
# Cmocka tests
|
||||
#
|
||||
+bld.SAMBA_BINARY('test_ndr_macros',
|
||||
+ source='tests/test_ndr_macros.c',
|
||||
+ deps='''
|
||||
+ cmocka
|
||||
+ ndr
|
||||
+ ''',
|
||||
+ for_selftest=True)
|
||||
+
|
||||
bld.SAMBA_BINARY('test_ndr_string',
|
||||
source='tests/test_ndr_string.c',
|
||||
deps='''
|
||||
diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py
|
||||
index 5cdb3d27b77..389a142db7d 100755
|
||||
--- a/source4/selftest/tests.py
|
||||
+++ b/source4/selftest/tests.py
|
||||
@@ -1346,6 +1346,8 @@ plantestsuite("librpc.ndr.ndr_string", "none",
|
||||
[os.path.join(bindir(), "test_ndr_dns_nbt")])
|
||||
plantestsuite("libcli.ldap.ldap_message", "none",
|
||||
[os.path.join(bindir(), "test_ldap_message")])
|
||||
+plantestsuite("librpc.ndr.ndr_macros", "none",
|
||||
+ [os.path.join(bindir(), "test_ndr_macros")])
|
||||
|
||||
# process restart and limit tests, these break the environment so need to run
|
||||
# in their own specific environment
|
||||
--
|
||||
GitLab
|
||||
|
||||
@ -0,0 +1,110 @@
|
||||
From a97c78fb221a2f1aaca2effdb44c51e4f78ddd93 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Metzmacher <metze@samba.org>
|
||||
Date: Thu, 7 Nov 2019 10:03:36 +0100
|
||||
Subject: [PATCH] lzxpress: add bounds checking to lzxpress_decompress()
|
||||
|
||||
lzxpress_decompress() would wander past the end of the array in
|
||||
numerous locations.
|
||||
|
||||
Credit to OSS-Fuzz.
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14190
|
||||
REF: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=19382
|
||||
REF: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=20083
|
||||
REF: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=22485
|
||||
REF: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=22667
|
||||
|
||||
Signed-off-by: Stefan Metzmacher <metze@samba.org>
|
||||
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
|
||||
Autobuild-User(master): Douglas Bagnall <dbagnall@samba.org>
|
||||
Autobuild-Date(master): Sun Aug 9 00:30:26 UTC 2020 on sn-devel-184
|
||||
---
|
||||
lib/compression/lzxpress.c | 32 ++++++++++++++++++++++++++++++--
|
||||
1 file changed, 30 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/lib/compression/lzxpress.c b/lib/compression/lzxpress.c
|
||||
index 024aba4c2ce..d8326304455 100644
|
||||
--- a/lib/compression/lzxpress.c
|
||||
+++ b/lib/compression/lzxpress.c
|
||||
@@ -252,8 +252,24 @@ ssize_t lzxpress_decompress(const uint8_t *input,
|
||||
offset = 0;
|
||||
nibble_index = 0;
|
||||
|
||||
+#define __CHECK_BYTES(__size, __index, __needed) do { \
|
||||
+ if (unlikely(__index >= __size)) { \
|
||||
+ return -1; \
|
||||
+ } else { \
|
||||
+ uint32_t __avail = __size - __index; \
|
||||
+ if (unlikely(__needed > __avail)) { \
|
||||
+ return -1; \
|
||||
+ } \
|
||||
+ } \
|
||||
+} while(0)
|
||||
+#define CHECK_INPUT_BYTES(__needed) \
|
||||
+ __CHECK_BYTES(input_size, input_index, __needed)
|
||||
+#define CHECK_OUTPUT_BYTES(__needed) \
|
||||
+ __CHECK_BYTES(max_output_size, output_index, __needed)
|
||||
+
|
||||
do {
|
||||
if (indicator_bit == 0) {
|
||||
+ CHECK_INPUT_BYTES(4);
|
||||
indicator = PULL_LE_UINT32(input, input_index);
|
||||
input_index += sizeof(uint32_t);
|
||||
indicator_bit = 32;
|
||||
@@ -266,10 +282,13 @@ ssize_t lzxpress_decompress(const uint8_t *input,
|
||||
* check whether the 4th bit of the value in indicator is set
|
||||
*/
|
||||
if (((indicator >> indicator_bit) & 1) == 0) {
|
||||
+ CHECK_INPUT_BYTES(1);
|
||||
+ CHECK_OUTPUT_BYTES(1);
|
||||
output[output_index] = input[input_index];
|
||||
input_index += sizeof(uint8_t);
|
||||
output_index += sizeof(uint8_t);
|
||||
} else {
|
||||
+ CHECK_INPUT_BYTES(2);
|
||||
length = PULL_LE_UINT16(input, input_index);
|
||||
input_index += sizeof(uint16_t);
|
||||
offset = length / 8;
|
||||
@@ -277,6 +296,7 @@ ssize_t lzxpress_decompress(const uint8_t *input,
|
||||
|
||||
if (length == 7) {
|
||||
if (nibble_index == 0) {
|
||||
+ CHECK_INPUT_BYTES(1);
|
||||
nibble_index = input_index;
|
||||
length = input[input_index] % 16;
|
||||
input_index += sizeof(uint8_t);
|
||||
@@ -286,9 +306,11 @@ ssize_t lzxpress_decompress(const uint8_t *input,
|
||||
}
|
||||
|
||||
if (length == 15) {
|
||||
+ CHECK_INPUT_BYTES(1);
|
||||
length = input[input_index];
|
||||
input_index += sizeof(uint8_t);
|
||||
if (length == 255) {
|
||||
+ CHECK_INPUT_BYTES(2);
|
||||
length = PULL_LE_UINT16(input, input_index);
|
||||
input_index += sizeof(uint16_t);
|
||||
length -= (15 + 7);
|
||||
@@ -299,10 +321,16 @@ ssize_t lzxpress_decompress(const uint8_t *input,
|
||||
}
|
||||
|
||||
length += 3;
|
||||
+ if (length == 0) {
|
||||
+ return -1;
|
||||
+ }
|
||||
|
||||
- do {
|
||||
- if ((output_index >= max_output_size) || ((offset + 1) > output_index)) break;
|
||||
+ if (offset >= output_index) {
|
||||
+ return -1;
|
||||
+ }
|
||||
+ CHECK_OUTPUT_BYTES(length);
|
||||
|
||||
+ do {
|
||||
output[output_index] = output[output_index - offset - 1];
|
||||
|
||||
output_index += sizeof(uint8_t);
|
||||
--
|
||||
GitLab
|
||||
|
||||
35
backport-lzxpress-avoid-technically-undefined-shift.patch
Normal file
35
backport-lzxpress-avoid-technically-undefined-shift.patch
Normal file
@ -0,0 +1,35 @@
|
||||
From 0c461f3bd589764c496b530f698e313df50667e6 Mon Sep 17 00:00:00 2001
|
||||
From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Date: Thu, 6 Aug 2020 17:17:01 +1200
|
||||
Subject: [PATCH] lzxpress: avoid technically undefined shift
|
||||
|
||||
UBSAN:
|
||||
|
||||
runtime error: left shift of 1 by 31 places cannot be represented in type 'int'
|
||||
|
||||
Credit to OSS-fuzz.
|
||||
|
||||
REF: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=22283
|
||||
|
||||
Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Reviewed-by: Gary Lockyer <gary@catalyst.net.nz>
|
||||
|
||||
Autobuild-User(master): Jeremy Allison <jra@samba.org>
|
||||
Autobuild-Date(master): Mon Aug 31 22:31:13 UTC 2020 on sn-devel-184
|
||||
---
|
||||
lib/compression/lzxpress.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/lib/compression/lzxpress.c b/lib/compression/lzxpress.c
|
||||
index d8326304455c..3453dd36f2aa 100644
|
||||
--- a/lib/compression/lzxpress.c
|
||||
+++ b/lib/compression/lzxpress.c
|
||||
@@ -180,7 +180,7 @@ ssize_t lzxpress_compress(const uint8_t *uncompressed,
|
||||
}
|
||||
}
|
||||
|
||||
- indic |= 1 << (32 - ((indic_bit % 32) + 1));
|
||||
+ indic |= 1U << (32 - ((indic_bit % 32) + 1));
|
||||
|
||||
if (best_len > 9) {
|
||||
if (nibble_index == 0) {
|
||||
52
backport-pidl-Add-recursive-depth-checks.patch
Normal file
52
backport-pidl-Add-recursive-depth-checks.patch
Normal file
@ -0,0 +1,52 @@
|
||||
From 5d323f2a2e36c23a007d93394f25df0f3d30942d Mon Sep 17 00:00:00 2001
|
||||
From: Gary Lockyer <gary@catalyst.net.nz>
|
||||
Date: Thu, 30 Jan 2020 08:51:47 +1300
|
||||
Subject: [PATCH] pidl: Add recursive depth checks.
|
||||
|
||||
Add new parameter to elements "max_recursion" and modify pidl to call
|
||||
NDR_RECURSION_CHECK and NDR_RECURSION_UNWIND for element tagged with
|
||||
that attribute.
|
||||
|
||||
Credit to OSS-Fuzz
|
||||
|
||||
REF: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=19820
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14254
|
||||
|
||||
Signed-off-by: Gary Lockyer <gary@catalyst.net.nz>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
---
|
||||
pidl/lib/Parse/Pidl/NDR.pm | 1 +
|
||||
pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm | 7 +++++++
|
||||
2 files changed, 8 insertions(+)
|
||||
|
||||
diff --git a/pidl/lib/Parse/Pidl/NDR.pm b/pidl/lib/Parse/Pidl/NDR.pm
|
||||
index 44338a1298d8..d17d0b404ed0 100644
|
||||
--- a/pidl/lib/Parse/Pidl/NDR.pm
|
||||
+++ b/pidl/lib/Parse/Pidl/NDR.pm
|
||||
@@ -1101,6 +1101,7 @@ my %property_list = (
|
||||
"gensize" => ["TYPEDEF", "STRUCT", "UNION"],
|
||||
"value" => ["ELEMENT"],
|
||||
"flag" => ["ELEMENT", "TYPEDEF", "STRUCT", "UNION", "ENUM", "BITMAP", "PIPE"],
|
||||
+ "max_recursion" => ["ELEMENT"],
|
||||
|
||||
# generic
|
||||
"public" => ["FUNCTION", "TYPEDEF", "STRUCT", "UNION", "ENUM", "BITMAP", "PIPE"],
|
||||
diff --git a/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm b/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm
|
||||
index 0d58cb5f03d5..119590f66969 100644
|
||||
--- a/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm
|
||||
+++ b/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm
|
||||
@@ -993,7 +993,14 @@ sub ParseDataPull($$$$$$$)
|
||||
|
||||
$var_name = get_pointer_to($var_name);
|
||||
|
||||
+ if (my $depth = has_property($e, "max_recursion")) {
|
||||
+ my $d = parse_int($depth);
|
||||
+ $self->pidl("NDR_RECURSION_CHECK($ndr, $d);");
|
||||
+ }
|
||||
$self->pidl("NDR_CHECK(".TypeFunctionName("ndr_pull", $l->{DATA_TYPE})."($ndr, $ndr_flags, $var_name));");
|
||||
+ if (has_property($e, "max_recursion")) {
|
||||
+ $self->pidl("NDR_RECURSION_UNWIND($ndr);");
|
||||
+ }
|
||||
|
||||
my $pl = GetPrevLevel($e, $l);
|
||||
|
||||
38
backport-utils-asn1-avoid-undefined-behaviour.patch
Normal file
38
backport-utils-asn1-avoid-undefined-behaviour.patch
Normal file
@ -0,0 +1,38 @@
|
||||
From ed9abf94b3167a1a61b5da163e9b07b06c8a457b Mon Sep 17 00:00:00 2001
|
||||
From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Date: Sun, 6 Sep 2020 09:35:49 +1200
|
||||
Subject: [PATCH] utils/asn1: avoid undefined behaviour warning
|
||||
|
||||
UBSAN does not like an int >= 1<<24 being shifted left.
|
||||
We check the overflow in the very next line.
|
||||
|
||||
Credit to OSS-Fuzz.
|
||||
|
||||
REF: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=25436
|
||||
|
||||
Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
|
||||
Autobuild-User(master): Andrew Bartlett <abartlet@samba.org>
|
||||
Autobuild-Date(master): Fri Sep 11 05:05:59 UTC 2020 on sn-devel-184
|
||||
---
|
||||
lib/util/asn1.c | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/lib/util/asn1.c b/lib/util/asn1.c
|
||||
index 6b1b4bc2877f..9ab9e1b08449 100644
|
||||
--- a/lib/util/asn1.c
|
||||
+++ b/lib/util/asn1.c
|
||||
@@ -1071,7 +1071,11 @@ bool asn1_read_enumerated(struct asn1_data *data, int *v)
|
||||
if (!asn1_read_uint8(data, &b)) {
|
||||
return false;
|
||||
}
|
||||
- *v = (*v << 8) + b;
|
||||
+ /*
|
||||
+ * To please/fool the Undefined Behaviour Sanitizer we cast to
|
||||
+ * unsigned for the left shift.
|
||||
+ */
|
||||
+ *v = ((unsigned int)*v << 8) + b;
|
||||
}
|
||||
return asn1_end_tag(data);
|
||||
}
|
||||
@ -0,0 +1,50 @@
|
||||
From 8cce23acb9f9bdde8bff3c3a7ffa83361e3a64a6 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Metzmacher <metze@samba.org>
|
||||
Date: Fri, 31 Jul 2020 11:27:25 +0200
|
||||
Subject: [PATCH] witness.idl: fix length calculation for
|
||||
witness_IPaddrInfoList
|
||||
|
||||
If r->num is 0, we should not dereference r->addr.
|
||||
|
||||
Using ndr_size_witness_IPaddrInfoList() also make this much simpler
|
||||
and avoids the magic 12.
|
||||
|
||||
Credit Oss-Fuzz
|
||||
|
||||
REF: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=22175
|
||||
REF: https://oss-fuzz.com/testcase-detail/5686294157197312
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14452
|
||||
|
||||
Signed-off-by: Stefan Metzmacher <metze@samba.org>
|
||||
Reviewed-by: Samuel Cabrero <scabrero@samba.org>
|
||||
---
|
||||
librpc/idl/witness.idl | 6 +++---
|
||||
source4/torture/ndr/witness.c | 24 ------------------------
|
||||
2 files changed, 3 insertions(+), 27 deletions(-)
|
||||
|
||||
diff --git a/librpc/idl/witness.idl b/librpc/idl/witness.idl
|
||||
index e230a5ea709..652c0e9cb65 100644
|
||||
--- a/librpc/idl/witness.idl
|
||||
+++ b/librpc/idl/witness.idl
|
||||
@@ -98,14 +98,14 @@ interface witness
|
||||
WITNESS_IPADDR_OFFLINE = 0x10
|
||||
} witness_IPaddrInfo_flags;
|
||||
|
||||
- typedef [flag(NDR_NOALIGN|NDR_LITTLE_ENDIAN),gensize] struct {
|
||||
+ typedef [flag(NDR_NOALIGN|NDR_LITTLE_ENDIAN)] struct {
|
||||
witness_IPaddrInfo_flags flags;
|
||||
[flag(NDR_BIG_ENDIAN)] ipv4address ipv4;
|
||||
[flag(NDR_BIG_ENDIAN)] ipv6address ipv6;
|
||||
} witness_IPaddrInfo;
|
||||
|
||||
- typedef [flag(NDR_NOALIGN|NDR_LITTLE_ENDIAN)] struct {
|
||||
- [value(12+(r->num*ndr_size_witness_IPaddrInfo(r->addr, ndr->flags)))] uint32 length;
|
||||
+ typedef [public,flag(NDR_NOALIGN|NDR_LITTLE_ENDIAN),gensize] struct {
|
||||
+ [value(ndr_size_witness_IPaddrInfoList(r, ndr->flags))] uint32 length;
|
||||
[value(0)] uint32 reserved;
|
||||
uint32 num;
|
||||
witness_IPaddrInfo addr[num];
|
||||
--
|
||||
GitLab
|
||||
|
||||
30
samba.spec
30
samba.spec
@ -49,7 +49,7 @@
|
||||
|
||||
Name: samba
|
||||
Version: 4.12.5
|
||||
Release: 7
|
||||
Release: 8
|
||||
|
||||
Summary: A suite for Linux to interoperate with Windows
|
||||
License: GPLv3+ and LGPLv3+
|
||||
@ -75,6 +75,17 @@ Patch5: CVE-2021-20277.patch
|
||||
Patch6: CVE-2020-27840.patch
|
||||
Patch7: CVE-2021-20254.patch
|
||||
Patch8: backport-CVE-2021-3671.patch
|
||||
Patch9: backport-lzxpress-add-bounds-checking-to-lzxpress_decompress.patch
|
||||
Patch10: backport-librpc-ndr-NDR_PULL_ALIGN-check-for-unsigned-overflow.patch
|
||||
Patch11: backport-librpc-ndr-add-recursion-check-macros.patch
|
||||
Patch12: backport-librpc-ndr-Heap-buffer-overflow-in-lzxpress_decompress.patch
|
||||
Patch13: backport-pidl-Add-recursive-depth-checks.patch
|
||||
Patch14: backport-idl-drsuapi_DsaAddressListItem_V1-limit-recursion.patch
|
||||
Patch15: backport-idl-limit-recurion-on-recursive-elements.patch
|
||||
Patch16: backport-lib-ldb-Limit-depth-of-ldb_parse_tree.patch
|
||||
Patch17: backport-witness-idl-fix-length-calculation-for-witness_IPaddrInfoList.patch
|
||||
Patch18: backport-lzxpress-avoid-technically-undefined-shift.patch
|
||||
Patch19: backport-utils-asn1-avoid-undefined-behaviour.patch
|
||||
|
||||
BuildRequires: avahi-devel bison cups-devel dbus-devel docbook-style-xsl e2fsprogs-devel flex 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
|
||||
@ -3209,6 +3220,23 @@ fi
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Fri Oct 29 2021 gaihuiying <gaihuiying1@huawei.com> - 4.12.5-8
|
||||
- Type:bugfix
|
||||
- ID:NA
|
||||
- SUG:NA
|
||||
- DESC:fix fuzz error:
|
||||
idl: drsuapi_DsaAddressListItem_V1 limit recursion
|
||||
idl: limit recurion on recursive-elements
|
||||
lib: ldb Limit depth of ldb_parse_tree
|
||||
librpc: ndr add recursion check macros
|
||||
librpc: ndr Heap-buffer-overflow in lzxpress_decompress
|
||||
librpc: ndr NDR_PULL_ALIGN check for unsigned overflow
|
||||
lzxpress: add bounds checking to lzxpress decompress
|
||||
lzxpress: avoid technically undefined shift
|
||||
pidl: Add recursive depth checks
|
||||
utils: asn1 avoid undefined behaviour
|
||||
witness: idl fix length calculation for witness_IPaddrInfoList
|
||||
|
||||
* Mon Oct 25 2021 gaihuiying <gaihuiying1@huawei.com> - 4.12.5-7
|
||||
- Type:cves
|
||||
- ID:CVE-2021-3671
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user