|
|
31affc |
From ab7848a4a30d79c7433a1689ba1ea18897b73453 Mon Sep 17 00:00:00 2001
|
|
|
31affc |
From: Mark Reynolds <mreynolds@redhat.com>
|
|
|
31affc |
Date: Tue, 18 Sep 2018 16:39:26 -0400
|
|
|
31affc |
Subject: [PATCH] Bug 1624004 - potential denial of service attack
|
|
|
31affc |
|
|
|
31affc |
Bug: a search request passing 8MB of NULL bytes as search attributes will
|
|
|
31affc |
keep one thread busy for a long time.
|
|
|
31affc |
The reason is that the attr array is copied/normalized to the searchattrs in
|
|
|
31affc |
the search operation and does this using charray_add() which iterates thru
|
|
|
31affc |
the array to determine the size of the array and then allocate one element more.
|
|
|
31affc |
so this means we iterat 8 million times an array with a then average size of
|
|
|
31affc |
4 million elements.
|
|
|
31affc |
|
|
|
31affc |
Fix: We already have traversed the array once and know the size, so we can allocate
|
|
|
31affc |
the needed size once and only copy the element.
|
|
|
31affc |
In addition we check for the kind of degenerated attributes "" as used in this
|
|
|
31affc |
test scenario.
|
|
|
31affc |
So the fix will reject invalid attr liste and improve performance for valid ones
|
|
|
31affc |
|
|
|
31affc |
https://bugzilla.redhat.com/show_bug.cgi?id=1624004
|
|
|
31affc |
---
|
|
|
31affc |
ldap/servers/slapd/search.c | 16 ++++++++++++++--
|
|
|
31affc |
ldap/servers/slapd/unbind.c | 4 ++--
|
|
|
31affc |
2 files changed, 16 insertions(+), 4 deletions(-)
|
|
|
31affc |
|
|
|
31affc |
diff --git a/ldap/servers/slapd/search.c b/ldap/servers/slapd/search.c
|
|
|
31affc |
index 731c6519e..dc26fc4d2 100644
|
|
|
31affc |
--- a/ldap/servers/slapd/search.c
|
|
|
31affc |
+++ b/ldap/servers/slapd/search.c
|
|
|
31affc |
@@ -209,6 +209,7 @@ do_search(Slapi_PBlock *pb)
|
|
|
31affc |
if (attrs != NULL) {
|
|
|
31affc |
char *normaci = slapi_attr_syntax_normalize("aci");
|
|
|
31affc |
int replace_aci = 0;
|
|
|
31affc |
+ int attr_count = 0;
|
|
|
31affc |
if (!normaci) {
|
|
|
31affc |
normaci = slapi_ch_strdup("aci");
|
|
|
31affc |
} else if (strcasecmp(normaci, "aci")) {
|
|
|
31affc |
@@ -218,9 +219,19 @@ do_search(Slapi_PBlock *pb)
|
|
|
31affc |
/*
|
|
|
31affc |
* . store gerattrs if any
|
|
|
31affc |
* . add "aci" once if "*" is given
|
|
|
31affc |
+ * . check that attrs are not degenerated
|
|
|
31affc |
*/
|
|
|
31affc |
for (i = 0; attrs[i] != NULL; i++) {
|
|
|
31affc |
char *p = NULL;
|
|
|
31affc |
+ attr_count++;
|
|
|
31affc |
+
|
|
|
31affc |
+ if ( attrs[i][0] == '\0') {
|
|
|
31affc |
+ log_search_access(pb, base, scope, fstr, "invalid attribute request");
|
|
|
31affc |
+ send_ldap_result(pb, LDAP_PROTOCOL_ERROR, NULL, NULL, 0, NULL);
|
|
|
31affc |
+ slapi_ch_free_string(&normaci);
|
|
|
31affc |
+ goto free_and_return;
|
|
|
31affc |
+ }
|
|
|
31affc |
+
|
|
|
31affc |
/* check if @<objectclass> is included */
|
|
|
31affc |
p = strchr(attrs[i], '@');
|
|
|
31affc |
if (p) {
|
|
|
31affc |
@@ -244,6 +255,7 @@ do_search(Slapi_PBlock *pb)
|
|
|
31affc |
} else if (strcmp(attrs[i], LDAP_ALL_USER_ATTRS /* '*' */) == 0) {
|
|
|
31affc |
if (!charray_inlist(attrs, normaci)) {
|
|
|
31affc |
charray_add(&attrs, slapi_ch_strdup(normaci));
|
|
|
31affc |
+ attr_count++;
|
|
|
31affc |
}
|
|
|
31affc |
} else if (replace_aci && (strcasecmp(attrs[i], "aci") == 0)) {
|
|
|
31affc |
slapi_ch_free_string(&attrs[i]);
|
|
|
31affc |
@@ -263,13 +275,13 @@ do_search(Slapi_PBlock *pb)
|
|
|
31affc |
}
|
|
|
31affc |
} else {
|
|
|
31affc |
/* return the chopped type, e.g., "sn" */
|
|
|
31affc |
- operation->o_searchattrs = NULL;
|
|
|
31affc |
+ operation->o_searchattrs = (char **)slapi_ch_calloc(sizeof(char *), attr_count+1);
|
|
|
31affc |
for (i = 0; attrs[i] != NULL; i++) {
|
|
|
31affc |
char *type;
|
|
|
31affc |
type = slapi_attr_syntax_normalize_ext(attrs[i],
|
|
|
31affc |
ATTR_SYNTAX_NORM_ORIG_ATTR);
|
|
|
31affc |
/* attrs[i] is consumed */
|
|
|
31affc |
- charray_add(&operation->o_searchattrs, attrs[i]);
|
|
|
31affc |
+ operation->o_searchattrs[i] = attrs[i];
|
|
|
31affc |
attrs[i] = type;
|
|
|
31affc |
}
|
|
|
31affc |
}
|
|
|
31affc |
diff --git a/ldap/servers/slapd/unbind.c b/ldap/servers/slapd/unbind.c
|
|
|
31affc |
index 90f7b1546..686e27a8e 100644
|
|
|
31affc |
--- a/ldap/servers/slapd/unbind.c
|
|
|
31affc |
+++ b/ldap/servers/slapd/unbind.c
|
|
|
31affc |
@@ -87,8 +87,8 @@ do_unbind(Slapi_PBlock *pb)
|
|
|
31affc |
/* pass the unbind to all backends */
|
|
|
31affc |
be_unbindall(pb_conn, operation);
|
|
|
31affc |
|
|
|
31affc |
+free_and_return:;
|
|
|
31affc |
+
|
|
|
31affc |
/* close the connection to the client */
|
|
|
31affc |
disconnect_server(pb_conn, operation->o_connid, operation->o_opid, SLAPD_DISCONNECT_UNBIND, 0);
|
|
|
31affc |
-
|
|
|
31affc |
-free_and_return:;
|
|
|
31affc |
}
|
|
|
31affc |
--
|
|
|
31affc |
2.17.1
|
|
|
31affc |
|