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

delete multiple attr can SEGV

  I was running into a SEGV in my OpenLDAP 2.0 slapd that I can't entirely
figure out. It happens when there is a single value in an attribute and a
request comes in to delete two values. The SEGV came in the function 
delete_values() in the LDBM back end, in the file modify.c.  There are two
for() loops, one on "i" that cycles through the values that the user has
requested be deleted, and the inner loop "j" that cycles through the values
that are in the database. The first value for "i" matches the first and 
only db value, so the "j" loop deletes it from the array of attrs, and
collapses the upper values of the array down one to fill in the gap. It
was the last value, so attr_delete is called.  Then the outer "i" loop
moves on to the next value the user requested. As the loop starts, the
first attr pointer is NULL, since the array was collapsed by one. When the
next value to be deleted is normalized using value_normalize(), that first
attr pointer goes from NULL to something else. The something else it
points to is a berval with len=8 and val=NULL. When that gets read by
anything, reading from the NULL val will SEGV. I watched this weird
change from NULL to non-NULL happen, and it occurs when the
UTF8StringNormalize() function (in schema_init.c) calls ch_strdup().  This
suggests to me that the array of attrs is using unallocated memory, but
I can't figure out where. I suspect it is related to deleting the first
(and only) value in the array.
  To patch around this, I added a check before the normalize function is

	for ( i = 0; mod->sm_bvalues[i] != NULL; i++ ) {
		int rc;
		const char *text = NULL;

		struct berval *asserted;

+		if ( a->a_vals[0] == NULL) {
+		}

		rc = value_normalize( mod->sm_desc,
			&text );

But this is just a workaround to the problem, I think. Can anyone else
read that delete_values() function and see if any memory mis-management is

   -Mark Adamson
    Carnegie Mellon