ldap/servers/slapd/valueset.c | 26 ++++++++++++++++++++++----
1 file changed, 22 insertions(+), 4 deletions(-)
New commits:
commit ed89524bd7499419ebd31531d6a91c0284f60f81
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Mon Jul 29 12:36:02 2013 -0600
Ticket #47448 - Segfault in 389-ds-base-1.3.1.4-1.fc19 when setting up FreeIPA
replication
https://fedorahosted.org/389/ticket/47448
Reviewed by: lkrispenz (Thanks!)
Branch: master
Fix Description: valueset_add_valueset() sets the values in the vs1
destination valueset. It expects that vs1 is empty. Particularly, the
sorted array. If the source valueset vs2->sorted is NULL, it assumes
vs1->sorted is NULL already, and does not free it and set it to NULL.
The fix is to free both vs1->sorted and vs1->va. NOTE: this fixes
the crash, but does not address the larger issue that the semantics of
valueset_add_valueset are not correct - valueset_add_valueset should add
the values from vs2 to vs1, rather than replace vs1 with vs2.
Also added post-condition assertions.
Platforms tested: RHEL6 x86_64
Flag Day: no
Doc impact: no
diff --git a/ldap/servers/slapd/valueset.c b/ldap/servers/slapd/valueset.c
index 416a838..de576ec 100644
--- a/ldap/servers/slapd/valueset.c
+++ b/ldap/servers/slapd/valueset.c
@@ -605,6 +605,7 @@ slapi_valueset_done(Slapi_ValueSet *vs)
{
if(vs!=NULL)
{
+ PR_ASSERT((vs->sorted == NULL) || (vs->num == 0) || ((vs->sorted[0] >= 0)
&& (vs->sorted[0] < vs->num)));
if(vs->va!=NULL)
{
valuearray_free(&vs->va);
@@ -636,6 +637,7 @@ slapi_valueset_set_from_smod(Slapi_ValueSet *vs, Slapi_Mod *smod)
Slapi_Value **va= NULL;
valuearray_init_bervalarray(slapi_mod_get_ldapmod_byref(smod)->mod_bvalues,
&va);
valueset_set_valuearray_passin(vs, va);
+ PR_ASSERT((vs->sorted == NULL) || (vs->num == 0) || ((vs->sorted[0] >= 0)
&& (vs->sorted[0] < vs->num)));
}
void
@@ -656,7 +658,7 @@ valueset_set_valuearray_byval(Slapi_ValueSet *vs, Slapi_Value
**addvals)
}
}
vs->va[j] = NULL;
-
+ PR_ASSERT((vs->sorted == NULL) || (vs->num == 0) || ((vs->sorted[0] >= 0)
&& (vs->sorted[0] < vs->num)));
}
void
@@ -666,6 +668,7 @@ valueset_set_valuearray_passin(Slapi_ValueSet *vs, Slapi_Value
**addvals)
vs->va= addvals;
vs->num = valuearray_count(addvals);
vs->max = vs->num + 1;
+ PR_ASSERT((vs->sorted == NULL) || (vs->num == 0) || ((vs->sorted[0] >= 0)
&& (vs->sorted[0] < vs->num)));
}
void
@@ -765,24 +768,27 @@ valueset_remove_value_sorted(const Slapi_Attr *a, Slapi_ValueSet
*vs, const Slap
for (i=0; i < vs->num; i++) {
if (vs->sorted[i] > index) vs->sorted[i]--;
}
+ PR_ASSERT((vs->sorted == NULL) || (vs->num == 0) || ((vs->sorted[0] >= 0)
&& (vs->sorted[0] < vs->num)));
}
return r;
}
+
Slapi_Value *
valueset_remove_value(const Slapi_Attr *a, Slapi_ValueSet *vs, const Slapi_Value *v)
{
+ Slapi_Value *r = NULL;
if (vs->sorted) {
- return (valueset_remove_value_sorted(a, vs, v));
+ r = valueset_remove_value_sorted(a, vs, v);
} else {
- Slapi_Value *r= NULL;
if(!valuearray_isempty(vs->va))
{
r= valuearray_remove_value(a, vs->va, v);
if (r)
vs->num--;
}
- return r;
}
+ PR_ASSERT((vs->sorted == NULL) || (vs->num == 0) || ((vs->sorted[0] >= 0)
&& (vs->sorted[0] < vs->num)));
+ return r;
}
/*
@@ -809,6 +815,7 @@ valueset_purge(Slapi_ValueSet *vs, const CSN *csn)
slapi_ch_free ((void **)&vs->sorted);
vs->sorted = NULL;
}
+ PR_ASSERT((vs->sorted == NULL) || (vs->num == 0) || ((vs->sorted[0] >= 0)
&& (vs->sorted[0] < vs->num)));
}
return 0;
}
@@ -999,6 +1006,7 @@ valueset_array_to_sorted (const Slapi_Attr *a, Slapi_ValueSet *vs)
}
vs->sorted[j+1] = swap;
}
+ PR_ASSERT((vs->sorted == NULL) || (vs->num == 0) || ((vs->sorted[0] >= 0)
&& (vs->sorted[0] < vs->num)));
}
/* insert a value into a sorted array, if dupcheck is set no duplicate values will be
accepted
* (is there a reason to allow duplicates ? LK
@@ -1014,10 +1022,12 @@ valueset_insert_value_to_sorted(const Slapi_Attr *a,
Slapi_ValueSet *vs, Slapi_V
if (vs->num == 0) {
vs->sorted[0] = 0;
vs->num++;
+ PR_ASSERT((vs->sorted == NULL) || (vs->num == 0) || ((vs->sorted[0] >= 0)
&& (vs->sorted[0] < vs->num)));
return(0);
} else if (valueset_value_cmp (a, vi, vs->va[vs->sorted[vs->num-1]]) > 0 )
{
vs->sorted[vs->num] = vs->num;
vs->num++;
+ PR_ASSERT((vs->sorted == NULL) || (vs->num == 0) || ((vs->sorted[0] >= 0)
&& (vs->sorted[0] < vs->num)));
return (vs->num);
}
v = valueset_find_sorted (a, vs, vi, &index);
@@ -1028,6 +1038,7 @@ valueset_insert_value_to_sorted(const Slapi_Attr *a, Slapi_ValueSet
*vs, Slapi_V
memmove(&vs->sorted[index+1],&vs->sorted[index],(vs->num - index)*
sizeof(int));
vs->sorted[index] = vs->num;
vs->num++;
+ PR_ASSERT((vs->sorted == NULL) || (vs->num == 0) || ((vs->sorted[0] >= 0)
&& (vs->sorted[0] < vs->num)));
return(index);
}
@@ -1116,6 +1127,7 @@ slapi_valueset_add_attr_valuearray_ext(const Slapi_Attr *a,
Slapi_ValueSet *vs,
}
(vs->va)[vs->num] = NULL;
+ PR_ASSERT((vs->sorted == NULL) || (vs->num == 0) || ((vs->sorted[0] >= 0)
&& (vs->sorted[0] < vs->num)));
return (rc);
}
@@ -1153,6 +1165,8 @@ valueset_add_valueset(Slapi_ValueSet *vs1, const Slapi_ValueSet
*vs2)
int i;
if (vs1 && vs2) {
+ valuearray_free(&vs1->va);
+ slapi_ch_free((void **)&vs1->sorted);
if (vs2->va) {
/* need to copy valuearray */
if (vs2->max == 0) {
@@ -1173,6 +1187,7 @@ valueset_add_valueset(Slapi_ValueSet *vs1, const Slapi_ValueSet
*vs2)
vs1->sorted = (int *) slapi_ch_malloc( vs1->max* sizeof(int));
memcpy(&vs1->sorted[0],&vs2->sorted[0],vs1->num* sizeof(int));
}
+ PR_ASSERT((vs1->sorted == NULL) || (vs1->num == 0) || ((vs1->sorted[0] >=
0) && (vs1->sorted[0] < vs1->num)));
}
}
@@ -1327,6 +1342,7 @@ valueset_replace_valuearray_ext(Slapi_Attr *a, Slapi_ValueSet *vs,
Slapi_Value *
vs->va = valstoreplace;
vs->num = vals_count;
vs->max = vals_count + 1;
+ PR_ASSERT((vs->sorted == NULL) || (vs->num == 0) || ((vs->sorted[0] >= 0)
&& (vs->sorted[0] < vs->num)));
} else {
/* verify the given values are not duplicated. */
Slapi_ValueSet *vs_new = slapi_valueset_new();
@@ -1347,6 +1363,7 @@ valueset_replace_valuearray_ext(Slapi_Attr *a, Slapi_ValueSet *vs,
Slapi_Value *
vs->num = vs_new->num;
vs->max = vs_new->max;
slapi_valueset_free (vs_new);
+ PR_ASSERT((vs->sorted == NULL) || (vs->num == 0) || ((vs->sorted[0] >= 0)
&& (vs->sorted[0] < vs->num)));
}
else
{
@@ -1354,6 +1371,7 @@ valueset_replace_valuearray_ext(Slapi_Attr *a, Slapi_ValueSet *vs,
Slapi_Value *
use them, just delete them */
slapi_valueset_free(vs_new);
valuearray_free(&valstoreplace);
+ PR_ASSERT((vs->sorted == NULL) || (vs->num == 0) || ((vs->sorted[0] >= 0)
&& (vs->sorted[0] < vs->num)));
}
}
return rc;