[Date Prev][Date Next] [Chronological] [Thread] [Top]

indexing can return NULL list (ITS#636)



I was loading a big feed into my 2.0 Beta slapd when the the server core
dumped. It was in the LDBM backend indexer() function in index.c. It had
called the substring indexer function, and was about to run key_change()
on the returned array of keys. The keys pointer was NULL, causing a
segmentation fault.


The indexer() function calls the substring indexer function for
whatever attribute it's working on, which is supposed to return an array
of keys in the last parameter. In this case, the indexer function was 
  caseIgnoreIA5SubstringsMatch()  in  servers/slapd/schema_init.c


If that substring matcher function finds that all of the values to index 
are too short to do a substring match, it points the array pointer to NULL
and returns LDAP_SUCCESS (see around line 1384, schema_init.c). The
indexer() function checks the return code, not the array pointer.  It sees
success, and then runs a for() loop on the keys, resulting in a SIGSEGV.

The indexer() function should check that the return code is LDAP_SUCCESS,
AND check if keys is non-NULL.   Another possible fix is for the substring
matcher function to NOT return SUCCESS if no values are indexable,
although non-success returns may trigger unhappiness in some other calling
functions.

I appended a patch for servers/slapd/back-ldbm/index.c

  -Mark Adamson
   Carnegie Mellon




--- .old/index.c        Tue Jun  6 13:43:21 2000
+++ index.c     Sun Jul 23 19:37:19 2000
@@ -174,7 +174,7 @@
                        ad->ad_type->sat_equality,
                        &prefix, vals, &keys );
 
-               if( rc == LDAP_SUCCESS ) {
+               if(( rc == LDAP_SUCCESS ) && ( keys != NULL)){
                        for( i= 0; keys[i] != NULL; i++ ) {
                                key_change( be, db, keys[i], id, op );
                        }
@@ -188,7 +188,7 @@
                        ad->ad_type->sat_approx,
                        &prefix, vals, &keys );
 
-               if( rc == LDAP_SUCCESS ) {
+               if(( rc == LDAP_SUCCESS ) && ( keys != NULL)){
                        for( i= 0; keys[i] != NULL; i++ ) {
                                key_change( be, db, keys[i], id, op );
                        }
@@ -202,7 +202,7 @@
                        ad->ad_type->sat_substr,
                        &prefix, vals, &keys );
 
-               if( rc == LDAP_SUCCESS ) {
+               if(( rc == LDAP_SUCCESS ) && ( keys != NULL)){
                        for( i= 0; keys[i] != NULL; i++ ) {
                                key_change( be, db, keys[i], id, op );
                        }