[Fedora-directory-commits] ldapserver/ldap/servers/slapd entry.c, 1.15, 1.16 filterentry.c, 1.7, 1.8 getfilelist.c, 1.7, 1.8 plugin_syntax.c, 1.5, 1.6 proto-slap.h, 1.34, 1.35 regex.c, 1.6, 1.7 sasl_map.c, 1.8, 1.9 slapi-private.h, 1.24, 1.25 vattr.c, 1.8, 1.9

Noriko Hosoi (nhosoi) fedora-directory-commits at redhat.com
Mon Jun 30 17:28:18 UTC 2008


Author: nhosoi

Update of /cvs/dirsec/ldapserver/ldap/servers/slapd
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv26906/slapd

Modified Files:
	entry.c filterentry.c getfilelist.c plugin_syntax.c 
	proto-slap.h regex.c sasl_map.c slapi-private.h vattr.c 
Log Message:
Resoves: #448831
Summary: attacker can tie up CPU in regex code
Description: when substring search is requested, sets the time limit based upon
the nsslapd-timelimit value.  Pass the timelimit (time_up) to the regular
expression function.  When the time is up, it returns the "Timelimit exceeded"
error.	Note: timelimit is applied non-Directory Manager users.



Index: entry.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/entry.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- entry.c	4 Jun 2008 22:22:55 -0000	1.15
+++ entry.c	30 Jun 2008 17:28:16 -0000	1.16
@@ -1843,7 +1843,7 @@
 														f->f_choice,
 														&f->f_ava );
 				} else if ( filter_type == FILTER_TYPE_SUBSTRING) {
-					*rc = plugin_call_syntax_filter_sub( tmp_attr,
+					*rc = plugin_call_syntax_filter_sub( NULL, tmp_attr,
 															&f->f_sub);
 				} else if ( filter_type == FILTER_TYPE_PRES ) {
 					/* type is there, that's all we need to know. */


Index: filterentry.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/filterentry.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- filterentry.c	18 Apr 2008 20:20:22 -0000	1.7
+++ filterentry.c	30 Jun 2008 17:28:16 -0000	1.8
@@ -693,7 +693,7 @@
 			rc = -1;
 			for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
 				if ( slapi_attr_type_cmp( f->f_sub_type, a->a_type, SLAPI_TYPE_CMP_SUBTYPE ) == 0 ) {
-					rc = plugin_call_syntax_filter_sub( a, &f->f_sub );
+					rc = plugin_call_syntax_filter_sub( pb, a, &f->f_sub );
 					if ( rc == 0 ) {
 						break;
 					}
@@ -726,8 +726,8 @@
 		rc = -1;
 		for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
 			if ( slapi_attr_type_cmp( f->f_sub_type, a->a_type, SLAPI_TYPE_CMP_SUBTYPE ) == 0 ) {
-				rc = plugin_call_syntax_filter_sub( a, &f->f_sub );
-				if ( rc == 0 ) {
+				rc = plugin_call_syntax_filter_sub( pb, a, &f->f_sub );
+				if ( rc == 0 || rc == LDAP_TIMELIMIT_EXCEEDED ) {
 					break;
 				}
 			}


Index: getfilelist.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/getfilelist.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- getfilelist.c	10 Nov 2006 23:45:40 -0000	1.7
+++ getfilelist.c	30 Jun 2008 17:28:16 -0000	1.8
@@ -130,7 +130,7 @@
 	slapd_re_lock();
 	s = slapd_re_comp((char *)pattern);
 	if (!s)
-		match = slapd_re_exec((char *)filename);
+		match = slapd_re_exec((char *)filename, -1 /* no timelimit */);
 	slapd_re_unlock();
 
 	return match;


Index: plugin_syntax.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/plugin_syntax.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- plugin_syntax.c	10 Nov 2006 23:45:40 -0000	1.5
+++ plugin_syntax.c	30 Jun 2008 17:28:16 -0000	1.6
@@ -211,15 +211,17 @@
 
 int
 plugin_call_syntax_filter_sub(
+    Slapi_PBlock	*pb,
     Slapi_Attr		*a,
     struct subfilt	*fsub
 )
 {
-	return(plugin_call_syntax_filter_sub_sv(a,fsub));
+	return(plugin_call_syntax_filter_sub_sv(pb,a,fsub));
 }
 
 int
 plugin_call_syntax_filter_sub_sv(
+    Slapi_PBlock	*pb,
     Slapi_Attr		*a,
     struct subfilt	*fsub
 )
@@ -240,6 +242,13 @@
 	{
 		Slapi_Value **va= valueset_get_valuearray(&a->a_present_values);
 		pblock_init( &pipb );
+		if (pb)
+		{
+			Operation *op = NULL;
+			/* to pass SLAPI_SEARCH_TIMELIMIT & SLAPI_OPINITATED_TIME */
+			slapi_pblock_get( pb, SLAPI_OPERATION, &op );
+			slapi_pblock_set( &pipb, SLAPI_OPERATION, op );
+		}
 		slapi_pblock_set( &pipb, SLAPI_PLUGIN, (void *) a->a_plugin );
 		rc = a->a_plugin->plg_syntax_filter_sub( &pipb,
 		    fsub->sf_initial, fsub->sf_any, fsub->sf_final, va);


Index: proto-slap.h
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/proto-slap.h,v
retrieving revision 1.34
retrieving revision 1.35
diff -u -r1.34 -r1.35
--- proto-slap.h	10 Jun 2008 18:50:07 -0000	1.34
+++ proto-slap.h	30 Jun 2008 17:28:16 -0000	1.35
@@ -745,8 +745,8 @@
 struct slapdplugin *slapi_get_global_syntax_plugins();
 int plugin_call_syntax_filter_ava( const Slapi_Attr *a, int ftype, struct ava *ava );
 int plugin_call_syntax_filter_ava_sv( const Slapi_Attr *a, int ftype, struct ava *ava, Slapi_Value **retVal, int useDeletedValues );
-int plugin_call_syntax_filter_sub( Slapi_Attr *a, struct subfilt *fsub );
-int plugin_call_syntax_filter_sub_sv( Slapi_Attr *a, struct subfilt *fsub );
+int plugin_call_syntax_filter_sub( Slapi_PBlock *pb, Slapi_Attr *a, struct subfilt *fsub );
+int plugin_call_syntax_filter_sub_sv( Slapi_PBlock *pb, Slapi_Attr *a, struct subfilt *fsub );
 int plugin_call_syntax_get_compare_fn(void *vpi, value_compare_fn_type *compare_fn);
 struct slapdplugin *plugin_syntax_find( const char *nameoroid );
 void plugin_syntax_enumerate( SyntaxEnumFunc sef, void *arg );


Index: regex.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/regex.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- regex.c	29 Apr 2008 00:38:36 -0000	1.6
+++ regex.c	30 Jun 2008 17:28:16 -0000	1.7
@@ -66,6 +66,14 @@
  * Modification history:
  *
  * $Log$
+ * Revision 1.7  2008/06/30 17:28:16  nhosoi
+ * Resoves: #448831
+ * Summary: attacker can tie up CPU in regex code
+ * Description: when substring search is requested, sets the time limit based upon
+ * the nsslapd-timelimit value.  Pass the timelimit (time_up) to the regular
+ * expression function.  When the time is up, it returns the "Timelimit exceeded"
+ * error.	Note: timelimit is applied non-Directory Manager users.
+ *
  * Revision 1.6  2008/04/29 00:38:36  nhosoi
  * Resolves: #182621 (#443955)
  * Summary: Allow larger regex buffer to enable long substring filters
@@ -695,7 +703,7 @@
 static UCHAR *bopat[MAXTAG];
 static UCHAR *eopat[MAXTAG];
 #ifdef NEEDPROTOS
-static UCHAR *pmatch( UCHAR *lp, UCHAR *ap );
+static UCHAR *pmatch( UCHAR *lp, UCHAR *ap, time_t time_up, int *err );
 #else /* NEEDPROTOS */
 static UCHAR *pmatch();
 #endif /* NEEDPROTOS */
@@ -720,14 +728,18 @@
  *	to the beginning and the end of the matched fragment,
  *	respectively.
  *
+ *  return values: 0 -- did not match
+ *                 1 -- matched
+ *                 othersise -- ldap error (TIMELIMIT_EXCEEDED only)
  */
 
 int
-slapd_re_exec( char *lp )
+slapd_re_exec( char *lp, time_t time_up )
 {
 	register UCHAR c;
 	register UCHAR *ep = 0;
 	register UCHAR *ap = nfa;
+	int ldaperror = 0;
 
 	bol = (UCHAR*)lp;
 
@@ -745,7 +757,7 @@
 	switch(*ap) {
 
 	case BOL:			/* anchored: match from BOL only */
-		ep = pmatch((UCHAR*)lp,ap);
+		ep = pmatch((UCHAR*)lp,ap,time_up,&ldaperror);
 		break;
 	case CHR:			/* ordinary char: locate it fast */
 		c = *(ap+1);
@@ -755,7 +767,7 @@
 			return 0;
 	default:			/* regular matching all the way. */
 		do {
-			if ((ep = pmatch((UCHAR*)lp,ap)))
+			if ((ep = pmatch((UCHAR*)lp,ap,time_up,&ldaperror)))
 				break;
 			lp++;
 		} while (*lp);
@@ -764,6 +776,8 @@
 	case END:			/* munged automaton. fail always */
 		return 0;
 	}
+	if (ldaperror)
+		return ldaperror;
 	if (!ep)
 		return 0;
 
@@ -844,13 +858,19 @@
 #define CCLSKIP 18	/* [CLO] CCL 16bytes END ... */
 
 static UCHAR *
-pmatch( UCHAR *lp, UCHAR *ap)
+pmatch( UCHAR *lp, UCHAR *ap, time_t time_up, int *err )
 {
 	register int op, c, n;
 	register UCHAR *e;		/* extra pointer for CLO */
 	register UCHAR *bp;		/* beginning of subpat.. */
 	register UCHAR *ep;		/* ending of subpat..	 */
 	UCHAR *are;			/* to save the line ptr. */
+	time_t curtime = current_time();
+
+	if ( time_up != -1 && curtime > time_up ) {
+		*err = LDAP_TIMELIMIT_EXCEEDED;
+		return 0;
+	}
 
 	while ((op = *ap++) != END)
 		switch(op) {
@@ -927,7 +947,7 @@
 			ap += n;
 
 			while (lp >= are) {
-				if ((e = pmatch(lp, ap)) != NULL)
+				if ((e = pmatch(lp, ap, time_up, err)) != NULL)
 					return e;
 				--lp;
 			}


Index: sasl_map.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/sasl_map.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- sasl_map.c	10 Nov 2006 23:45:40 -0000	1.8
+++ sasl_map.c	30 Jun 2008 17:28:16 -0000	1.9
@@ -434,9 +434,10 @@
 	recomp_result = slapd_re_comp(dp->regular_expression);
 	if (recomp_result) {
 		LDAPDebug( LDAP_DEBUG_ANY, "sasl_map_check : re_comp failed for expression (%s)\n", dp->regular_expression, 0, 0 );
+	} else {
+		matched = slapd_re_exec(sasl_user_and_realm, -1 /* no timelimit */);
+		LDAPDebug( LDAP_DEBUG_TRACE, "regex: %s, id: %s, %s\n", dp->regular_expression, sasl_user_and_realm, matched ? "matched" : "didn't match" );
 	}
-	matched = slapd_re_exec(sasl_user_and_realm);
-	LDAPDebug( LDAP_DEBUG_TRACE, "regex: %s, id: %s, %s\n", dp->regular_expression, sasl_user_and_realm, matched ? "matched" : "didn't match" );
 	if (matched) {
 		if (matched == 1) {
 			/* Allocate buffers for the returned strings */


Index: slapi-private.h
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/slapi-private.h,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -r1.24 -r1.25
--- slapi-private.h	27 Jun 2008 19:28:21 -0000	1.24
+++ slapi-private.h	30 Jun 2008 17:28:16 -0000	1.25
@@ -1185,7 +1185,7 @@
 
 void bervalarray_add_berval_fast(struct berval ***vals, const struct berval *addval, int nvals, int *maxvals);
 
-int slapd_re_exec( char *lp );
+int slapd_re_exec( char *lp, time_t time_up );
 char *slapd_re_comp( char *pat );
 int slapd_re_subs( char *src, char* dst );
 void slapd_re_lock( void );


Index: vattr.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/vattr.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- vattr.c	1 Nov 2007 20:24:07 -0000	1.8
+++ vattr.c	30 Jun 2008 17:28:16 -0000	1.9
@@ -540,7 +540,7 @@
 									rc = plugin_call_syntax_filter_ava( a,
 															f->f_choice, &f->f_ava );
 								} else if ( filter_type == FILTER_TYPE_SUBSTRING) {
-									rc = plugin_call_syntax_filter_sub( a,
+									rc = plugin_call_syntax_filter_sub( pb, a,
 																		&f->f_sub);
 								}
 
@@ -611,7 +611,7 @@
 								    		
     	} else if ( filter_type == FILTER_TYPE_SUBSTRING ) {
 			
-			rc = test_substring_filter( NULL, e, f, 0 /* no access check */,
+			rc = test_substring_filter( pb, e, f, 0 /* no access check */,
 									0 /* do test filter */, &acl_test_done);
 				
 		} else if ( filter_type == FILTER_TYPE_PRES ) {




More information about the Fedora-directory-commits mailing list