!50 backport to fix fuzz error
From: @eaglegai Reviewed-by: @zengwefeng Signed-off-by: @zengwefeng
This commit is contained in:
commit
ad11e732db
@ -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
|
Name: samba
|
||||||
Version: 4.12.5
|
Version: 4.12.5
|
||||||
Release: 7
|
Release: 8
|
||||||
|
|
||||||
Summary: A suite for Linux to interoperate with Windows
|
Summary: A suite for Linux to interoperate with Windows
|
||||||
License: GPLv3+ and LGPLv3+
|
License: GPLv3+ and LGPLv3+
|
||||||
@ -75,6 +75,17 @@ Patch5: CVE-2021-20277.patch
|
|||||||
Patch6: CVE-2020-27840.patch
|
Patch6: CVE-2020-27840.patch
|
||||||
Patch7: CVE-2021-20254.patch
|
Patch7: CVE-2021-20254.patch
|
||||||
Patch8: backport-CVE-2021-3671.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: 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
|
BuildRequires: jansson-devel krb5-devel >= %{required_mit_krb5} libacl-devel libaio-devel libarchive-devel libattr-devel
|
||||||
@ -3209,6 +3220,23 @@ fi
|
|||||||
%endif
|
%endif
|
||||||
|
|
||||||
%changelog
|
%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
|
* Mon Oct 25 2021 gaihuiying <gaihuiying1@huawei.com> - 4.12.5-7
|
||||||
- Type:cves
|
- Type:cves
|
||||||
- ID:CVE-2021-3671
|
- ID:CVE-2021-3671
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user