andykimpe / rpms / 389-ds-base

Forked from rpms/389-ds-base 5 months ago
Clone

Blame 0110-Bug-1024552-DoS-due-to-improper-handling-of-ger-attr.patch

dc8c34
From 0e5e3049ae78eb566462c5fb572f91890bae4055 Mon Sep 17 00:00:00 2001
dc8c34
From: Rich Megginson <rmeggins@redhat.com>
dc8c34
Date: Tue, 29 Oct 2013 13:47:35 -0600
dc8c34
Subject: [PATCH] Bug 1024552 DoS due to improper handling of ger attr searches
dc8c34
dc8c34
https://bugzilla.redhat.com/show_bug.cgi?id=1024552
dc8c34
Reviewed by: nhosoi (Thanks!)
dc8c34
Branch: rhel-6.5
dc8c34
Fix Description: The traversal of the attr list looking for GER objectclasses
dc8c34
was modifying the same attribute twice, removing the "@" from it.  The second
dc8c34
time, since there was no "@" in the string, the strchr would return NULL, and
dc8c34
the code would not check for it.
dc8c34
The code was simplified and rewritten to use charray_merge_nodup
dc8c34
to build the gerattrs list with unique objectclass values, which I believe was
dc8c34
the intention of the original code.  I also added some error checking to look
dc8c34
for invalid attributes like "@name" "name@" and "name@name@name".
dc8c34
Platforms tested: RHEL6 x86_64
dc8c34
Flag Day: no
dc8c34
Doc impact: no
dc8c34
(cherry picked from commit 3a1ce9e326d9788be233f7edd9d7bad20efb9690)
dc8c34
(cherry picked from commit 47f1769dbd1618d0385fb3e5441219f9c280486b)
dc8c34
---
dc8c34
 ldap/servers/slapd/search.c |   79 +++++++++----------------------------------
dc8c34
 1 files changed, 16 insertions(+), 63 deletions(-)
dc8c34
dc8c34
diff --git a/ldap/servers/slapd/search.c b/ldap/servers/slapd/search.c
dc8c34
index 1a824b2..9f165a1 100644
dc8c34
--- a/ldap/servers/slapd/search.c
dc8c34
+++ b/ldap/servers/slapd/search.c
dc8c34
@@ -246,8 +246,6 @@ do_search( Slapi_PBlock *pb )
dc8c34
 	}
dc8c34
 
dc8c34
 	if ( attrs != NULL ) {
dc8c34
-		int gerattrsiz = 1;
dc8c34
-		int gerattridx = 0;
dc8c34
 		int aciin = 0;
dc8c34
 		/* 
dc8c34
 		 * . store gerattrs if any
dc8c34
@@ -257,66 +255,25 @@ do_search( Slapi_PBlock *pb )
dc8c34
 		{
dc8c34
 			char *p = NULL;
dc8c34
 			/* check if @<objectclass> is included */
dc8c34
-			p =  strchr(attrs[i], '@');
dc8c34
-			if ( p && '\0' != *(p+1) )	/* don't store "*@", e.g. */
dc8c34
+			p = strchr(attrs[i], '@');
dc8c34
+			if ( p )
dc8c34
 			{
dc8c34
-				int j = 0;
dc8c34
-				if (gerattridx + 1 >= gerattrsiz)
dc8c34
+				char *dummyary[2]; /* need a char ** for charray_merge_nodup */
dc8c34
+				if ((*(p + 1) == '\0') || (p == attrs[i]) || (strchr(p+1, '@'))) /* e.g. "foo@" or "@objectclassname" or "foo@bar@baz" */
dc8c34
 				{
dc8c34
-					char **tmpgerattrs;
dc8c34
-					gerattrsiz *= 2;
dc8c34
-					tmpgerattrs = 
dc8c34
-						(char **)slapi_ch_calloc(1, gerattrsiz*sizeof(char *));
dc8c34
-					if (NULL != gerattrs)
dc8c34
-					{
dc8c34
-						memcpy(tmpgerattrs, gerattrs, gerattrsiz*sizeof(char *));
dc8c34
-						slapi_ch_free((void **)&gerattrs);
dc8c34
-					}
dc8c34
-					gerattrs = tmpgerattrs;
dc8c34
-				}
dc8c34
-				for ( j = 0; gerattrs; j++ )
dc8c34
-				{
dc8c34
-					char *attri = NULL;
dc8c34
-					if ( NULL == gerattrs[j] )
dc8c34
-					{
dc8c34
-						if (0 == j)
dc8c34
-						{
dc8c34
-							/* first time */
dc8c34
-							gerattrs[gerattridx++] = attrs[i];
dc8c34
-							/* get rid of "@<objectclass>" part from the attr
dc8c34
-							   list, which is needed only in gerattr list */
dc8c34
-							*p = '\0';
dc8c34
-							attri = slapi_ch_strdup(attrs[i]);
dc8c34
-							attrs[i] = attri;
dc8c34
-							*p = '@';
dc8c34
-						}
dc8c34
-						else
dc8c34
-						{
dc8c34
-							break; /* done */
dc8c34
-						}
dc8c34
-					}
dc8c34
-					else if ( 0 == strcasecmp( attrs[i], gerattrs[j] ))
dc8c34
-					{
dc8c34
-						/* skip if attrs[i] is already in gerattrs */
dc8c34
-						continue;
dc8c34
-					}
dc8c34
-					else
dc8c34
-					{
dc8c34
-						char *q = strchr(gerattrs[j], '@'); /* q never be 0 */
dc8c34
-						if ( 0 != strcasecmp( p+1, q+1 ))
dc8c34
-						{
dc8c34
-							/* you don't want to display the same template
dc8c34
-							   entry multiple times */
dc8c34
-							gerattrs[gerattridx++] = attrs[i];
dc8c34
-						}
dc8c34
-						/* get rid of "@<objectclass>" part from the attr 
dc8c34
-						   list, which is needed only in gerattr list */
dc8c34
-						*p = '\0';
dc8c34
-						attri = slapi_ch_strdup(attrs[i]);
dc8c34
-						attrs[i] = attri;
dc8c34
-						*p = '@';
dc8c34
-					}
dc8c34
+					slapi_log_error( SLAPI_LOG_ARGS, "do_search",
dc8c34
+					                 "invalid attribute [%s] in list - must be of the form "
dc8c34
+					                 "attributename@objectclassname where attributename is the "
dc8c34
+					                 "name of an attribute or \"*\" or \"+\" and objectclassname "
dc8c34
+					                 "is the name of an objectclass\n", attrs[i] );
dc8c34
+					continue;
dc8c34
 				}
dc8c34
+				dummyary[0] = p; /* p = @objectclassname */
dc8c34
+				dummyary[1] = NULL;
dc8c34
+				/* copy string to gerattrs with leading @ - disallow dups */
dc8c34
+				charray_merge_nodup(&gerattrs, dummyary, 1);
dc8c34
+				/* null terminate the attribute name at the @ after it has been copied */
dc8c34
+				*p = '\0';
dc8c34
 			}
dc8c34
 			else if ( !aciin && strcasecmp(attrs[i], LDAP_ALL_USER_ATTRS) == 0 )
dc8c34
 			{
dc8c34
@@ -324,10 +281,6 @@ do_search( Slapi_PBlock *pb )
dc8c34
 				aciin = 1;
dc8c34
 			}
dc8c34
 		}
dc8c34
-		if (NULL != gerattrs)
dc8c34
-		{
dc8c34
-			gerattrs[gerattridx] = NULL;
dc8c34
-		}
dc8c34
 
dc8c34
 		/* Set attrs to SLAPI_SEARCH_ATTRS once to get rid of the forbidden attrs */
dc8c34
 		slapi_pblock_set( pb, SLAPI_SEARCH_ATTRS, attrs );
dc8c34
-- 
dc8c34
1.7.1
dc8c34