|
|
dc8c34 |
From 02e744fe208b912bbe51a0286457095211fbe2a2 Mon Sep 17 00:00:00 2001
|
|
|
dc8c34 |
From: Rich Megginson <rmeggins@redhat.com>
|
|
|
dc8c34 |
Date: Mon, 29 Jul 2013 12:36:02 -0600
|
|
|
dc8c34 |
Subject: [PATCH 192/225] Ticket #47448 - Segfault in
|
|
|
dc8c34 |
389-ds-base-1.3.1.4-1.fc19 when setting up FreeIPA replication
|
|
|
dc8c34 |
|
|
|
dc8c34 |
https://fedorahosted.org/389/ticket/47448
|
|
|
dc8c34 |
Reviewed by: lkrispenz (Thanks!)
|
|
|
dc8c34 |
Branch: master
|
|
|
dc8c34 |
Fix Description: valueset_add_valueset() sets the values in the vs1
|
|
|
dc8c34 |
destination valueset. It expects that vs1 is empty. Particularly, the
|
|
|
dc8c34 |
sorted array. If the source valueset vs2->sorted is NULL, it assumes
|
|
|
dc8c34 |
vs1->sorted is NULL already, and does not free it and set it to NULL.
|
|
|
dc8c34 |
The fix is to free both vs1->sorted and vs1->va. NOTE: this fixes
|
|
|
dc8c34 |
the crash, but does not address the larger issue that the semantics of
|
|
|
dc8c34 |
valueset_add_valueset are not correct - valueset_add_valueset should add
|
|
|
dc8c34 |
the values from vs2 to vs1, rather than replace vs1 with vs2.
|
|
|
dc8c34 |
Also added post-condition assertions.
|
|
|
dc8c34 |
Platforms tested: RHEL6 x86_64
|
|
|
dc8c34 |
Flag Day: no
|
|
|
dc8c34 |
Doc impact: no
|
|
|
dc8c34 |
(cherry picked from commit df53a874436503ef99594fc09e3d817317f86940)
|
|
|
dc8c34 |
|
|
|
dc8c34 |
Backported from 389-ds-base-1.3.1 to 389-ds-base-1.2.11.
|
|
|
dc8c34 |
The patch was reviewed by rmeggins@redhat.com (Thank you, Rich!!)
|
|
|
dc8c34 |
NOTE: this patch is needed for Ticket #346 - Slow ldapmodify operation
|
|
|
dc8c34 |
time for large quantities of multi-valued attribute values
|
|
|
dc8c34 |
(cherry picked from commit d36f7ea51cb8cb37d4d937dcf47254bf12a41c6b)
|
|
|
dc8c34 |
---
|
|
|
dc8c34 |
ldap/servers/slapd/valueset.c | 18 +++++++++++++++++-
|
|
|
dc8c34 |
1 file changed, 17 insertions(+), 1 deletion(-)
|
|
|
dc8c34 |
|
|
|
dc8c34 |
diff --git a/ldap/servers/slapd/valueset.c b/ldap/servers/slapd/valueset.c
|
|
|
dc8c34 |
index 29078d4..e83e740 100644
|
|
|
dc8c34 |
--- a/ldap/servers/slapd/valueset.c
|
|
|
dc8c34 |
+++ b/ldap/servers/slapd/valueset.c
|
|
|
dc8c34 |
@@ -573,6 +573,7 @@ slapi_valueset_done(Slapi_ValueSet *vs)
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
if(vs!=NULL)
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
+ PR_ASSERT((vs->sorted == NULL) || (vs->num == 0) || ((vs->sorted[0] >= 0) && (vs->sorted[0] < vs->num)));
|
|
|
dc8c34 |
if(vs->va!=NULL)
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
valuearray_free(&vs->va);
|
|
|
dc8c34 |
@@ -604,6 +605,7 @@ slapi_valueset_set_from_smod(Slapi_ValueSet *vs, Slapi_Mod *smod)
|
|
|
dc8c34 |
Slapi_Value **va= NULL;
|
|
|
dc8c34 |
valuearray_init_bervalarray(slapi_mod_get_ldapmod_byref(smod)->mod_bvalues, &va);
|
|
|
dc8c34 |
valueset_set_valuearray_passin(vs, va);
|
|
|
dc8c34 |
+ PR_ASSERT((vs->sorted == NULL) || (vs->num == 0) || ((vs->sorted[0] >= 0) && (vs->sorted[0] < vs->num)));
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
void
|
|
|
dc8c34 |
@@ -624,7 +626,7 @@ valueset_set_valuearray_byval(Slapi_ValueSet *vs, Slapi_Value **addvals)
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
vs->va[j] = NULL;
|
|
|
dc8c34 |
-
|
|
|
dc8c34 |
+ PR_ASSERT((vs->sorted == NULL) || (vs->num == 0) || ((vs->sorted[0] >= 0) && (vs->sorted[0] < vs->num)));
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
void
|
|
|
dc8c34 |
@@ -634,6 +636,7 @@ valueset_set_valuearray_passin(Slapi_ValueSet *vs, Slapi_Value **addvals)
|
|
|
dc8c34 |
vs->va= addvals;
|
|
|
dc8c34 |
vs->num = valuearray_count(addvals);
|
|
|
dc8c34 |
vs->max = vs->num + 1;
|
|
|
dc8c34 |
+ PR_ASSERT((vs->sorted == NULL) || (vs->num == 0) || ((vs->sorted[0] >= 0) && (vs->sorted[0] < vs->num)));
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
void
|
|
|
dc8c34 |
@@ -747,6 +750,7 @@ valueset_remove_value_sorted(const Slapi_Attr *a, Slapi_ValueSet *vs, const Slap
|
|
|
dc8c34 |
for (i=0; i < vs->num; i++) {
|
|
|
dc8c34 |
if (vs->sorted[i] > index) vs->sorted[i]--;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
+ PR_ASSERT((vs->sorted == NULL) || (vs->num == 0) || ((vs->sorted[0] >= 0) && (vs->sorted[0] < vs->num)));
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
return r;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
@@ -763,6 +767,7 @@ valueset_remove_value(const Slapi_Attr *a, Slapi_ValueSet *vs, const Slapi_Value
|
|
|
dc8c34 |
if (r)
|
|
|
dc8c34 |
vs->num--;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
+ PR_ASSERT((vs->sorted == NULL) || (vs->num == 0) || ((vs->sorted[0] >= 0) && (vs->sorted[0] < vs->num)));
|
|
|
dc8c34 |
return r;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
@@ -791,6 +796,7 @@ valueset_purge(Slapi_ValueSet *vs, const CSN *csn)
|
|
|
dc8c34 |
slapi_ch_free ((void **)&vs->sorted);
|
|
|
dc8c34 |
vs->sorted = NULL;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
+ PR_ASSERT((vs->sorted == NULL) || (vs->num == 0) || ((vs->sorted[0] >= 0) && (vs->sorted[0] < vs->num)));
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
return 0;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
@@ -980,6 +986,7 @@ valueset_array_to_sorted (const Slapi_Attr *a, Slapi_ValueSet *vs)
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
vs->sorted[j+1] = swap;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
+ PR_ASSERT((vs->sorted == NULL) || (vs->num == 0) || ((vs->sorted[0] >= 0) && (vs->sorted[0] < vs->num)));
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
/* insert a value into a sorted array, if dupcheck is set no duplicate values will be accepted
|
|
|
dc8c34 |
* (is there a reason to allow duplicates ? LK
|
|
|
dc8c34 |
@@ -995,10 +1002,12 @@ valueset_insert_value_to_sorted(const Slapi_Attr *a, Slapi_ValueSet *vs, Slapi_V
|
|
|
dc8c34 |
if (vs->num == 0) {
|
|
|
dc8c34 |
vs->sorted[0] = 0;
|
|
|
dc8c34 |
vs->num++;
|
|
|
dc8c34 |
+ PR_ASSERT((vs->sorted == NULL) || (vs->num == 0) || ((vs->sorted[0] >= 0) && (vs->sorted[0] < vs->num)));
|
|
|
dc8c34 |
return(0);
|
|
|
dc8c34 |
} else if (valueset_value_cmp (a, vi, vs->va[vs->sorted[vs->num-1]]) > 0 ) {
|
|
|
dc8c34 |
vs->sorted[vs->num] = vs->num;
|
|
|
dc8c34 |
vs->num++;
|
|
|
dc8c34 |
+ PR_ASSERT((vs->sorted == NULL) || (vs->num == 0) || ((vs->sorted[0] >= 0) && (vs->sorted[0] < vs->num)));
|
|
|
dc8c34 |
return (vs->num);
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
v = valueset_find_sorted (a, vs, vi, &index);
|
|
|
dc8c34 |
@@ -1009,6 +1018,7 @@ valueset_insert_value_to_sorted(const Slapi_Attr *a, Slapi_ValueSet *vs, Slapi_V
|
|
|
dc8c34 |
memmove(&vs->sorted[index+1],&vs->sorted[index],(vs->num - index)* sizeof(int));
|
|
|
dc8c34 |
vs->sorted[index] = vs->num;
|
|
|
dc8c34 |
vs->num++;
|
|
|
dc8c34 |
+ PR_ASSERT((vs->sorted == NULL) || (vs->num == 0) || ((vs->sorted[0] >= 0) && (vs->sorted[0] < vs->num)));
|
|
|
dc8c34 |
return(index);
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
@@ -1111,6 +1121,7 @@ slapi_valueset_add_attr_valuearray_ext(const Slapi_Attr *a, Slapi_ValueSet *vs,
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
(vs->va)[vs->num] = NULL;
|
|
|
dc8c34 |
|
|
|
dc8c34 |
+ PR_ASSERT((vs->sorted == NULL) || (vs->num == 0) || ((vs->sorted[0] >= 0) && (vs->sorted[0] < vs->num)));
|
|
|
dc8c34 |
return (rc);
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
@@ -1148,6 +1159,8 @@ valueset_add_valueset(Slapi_ValueSet *vs1, const Slapi_ValueSet *vs2)
|
|
|
dc8c34 |
int i;
|
|
|
dc8c34 |
|
|
|
dc8c34 |
if (vs1 && vs2) {
|
|
|
dc8c34 |
+ valuearray_free(&vs1->va);
|
|
|
dc8c34 |
+ slapi_ch_free((void **)&vs1->sorted);
|
|
|
dc8c34 |
if (vs2->va) {
|
|
|
dc8c34 |
/* need to copy valuearray */
|
|
|
dc8c34 |
if (vs2->max == 0) {
|
|
|
dc8c34 |
@@ -1168,6 +1181,7 @@ valueset_add_valueset(Slapi_ValueSet *vs1, const Slapi_ValueSet *vs2)
|
|
|
dc8c34 |
vs1->sorted = (int *) slapi_ch_malloc( vs1->max* sizeof(int));
|
|
|
dc8c34 |
memcpy(&vs1->sorted[0],&vs2->sorted[0],vs1->num* sizeof(int));
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
+ PR_ASSERT((vs1->sorted == NULL) || (vs1->num == 0) || ((vs1->sorted[0] >= 0) && (vs1->sorted[0] < vs1->num)));
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
@@ -1322,6 +1336,7 @@ valueset_replace_valuearray_ext(Slapi_Attr *a, Slapi_ValueSet *vs, Slapi_Value *
|
|
|
dc8c34 |
vs->va = valstoreplace;
|
|
|
dc8c34 |
vs->num = vals_count;
|
|
|
dc8c34 |
vs->max = vals_count + 1;
|
|
|
dc8c34 |
+ PR_ASSERT((vs->sorted == NULL) || (vs->num == 0) || ((vs->sorted[0] >= 0) && (vs->sorted[0] < vs->num)));
|
|
|
dc8c34 |
} else {
|
|
|
dc8c34 |
/* verify the given values are not duplicated. */
|
|
|
dc8c34 |
unsigned long flags = SLAPI_VALUE_FLAG_PASSIN|SLAPI_VALUE_FLAG_DUPCHECK;
|
|
|
dc8c34 |
@@ -1349,6 +1364,7 @@ valueset_replace_valuearray_ext(Slapi_Attr *a, Slapi_ValueSet *vs, Slapi_Value *
|
|
|
dc8c34 |
vs->num = vs_new->num;
|
|
|
dc8c34 |
vs->max = vs_new->max;
|
|
|
dc8c34 |
slapi_valueset_free (vs_new);
|
|
|
dc8c34 |
+ PR_ASSERT((vs->sorted == NULL) || (vs->num == 0) || ((vs->sorted[0] >= 0) && (vs->sorted[0] < vs->num)));
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
else
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
--
|
|
|
dc8c34 |
1.8.1.4
|
|
|
dc8c34 |
|