From 92af3c54655cdac45271d2111a53ba6bd6400052 Mon Sep 17 00:00:00 2001
From: Noriko Hosoi <nhosoi@redhat.com>
Date: Tue, 15 Sep 2015 18:25:02 -0700
Subject: [PATCH] Ticket #48226 - In MMR, double free coould occur under some
special condition
Description: commit a0f8e0f981a046882db299a7a6d6d1c01bc19571 introduced
a memory leak in the case of resolve_attribute_state_present_to_deleted.
In the case, csnset is not consumed. Thus, it has to be freed by csnset_
free.
https://fedorahosted.org/389/ticket/48226
Reviewed by mreynolds@redhat.com (Thank you, Mark!!)
(cherry picked from commit b26ec6762fe2b5d37ade59243086cfd2308e8f0a)
(cherry picked from commit 4a3efc3330a034fa485f33e453054758561d4cea)
(cherry picked from commit 14e08bde4a48a8e8b56edc817b5d1e3d56b96c72)
---
ldap/servers/slapd/entrywsi.c | 22 +++++++++++-----------
ldap/servers/slapd/valueset.c | 1 +
2 files changed, 12 insertions(+), 11 deletions(-)
diff --git a/ldap/servers/slapd/entrywsi.c b/ldap/servers/slapd/entrywsi.c
index 41afe1a..6773b9f 100644
--- a/ldap/servers/slapd/entrywsi.c
+++ b/ldap/servers/slapd/entrywsi.c
@@ -1305,23 +1305,23 @@ resolve_attribute_state_present_to_deleted(Slapi_Entry *e, Slapi_Attr *a, Slapi_
const CSN *adcsn= attr_get_deletion_csn(a);
int i;
if ( valuestoupdate != NULL && valuestoupdate[0] != NULL ) {
- for (i=0;valuestoupdate[i]!=NULL;++i) {
- /* This call ensures that the value does not contain a deletion_csn
- * which is before the presence_csn or distinguished_csn of the value.
- */
- purge_attribute_state_multi_valued(a, valuestoupdate[i]);
- vdcsn= value_get_csn(valuestoupdate[i], CSN_TYPE_VALUE_DELETED);
- vucsn= value_get_csn(valuestoupdate[i], CSN_TYPE_VALUE_UPDATED);
- deletedcsn= csn_max(vdcsn, adcsn);
+ for (i=0;valuestoupdate[i]!=NULL;++i) {
+ /* This call ensures that the value does not contain a deletion_csn
+ * which is before the presence_csn or distinguished_csn of the value.
+ */
+ purge_attribute_state_multi_valued(a, valuestoupdate[i]);
+ vdcsn= value_get_csn(valuestoupdate[i], CSN_TYPE_VALUE_DELETED);
+ vucsn= value_get_csn(valuestoupdate[i], CSN_TYPE_VALUE_UPDATED);
+ deletedcsn= csn_max(vdcsn, adcsn);
if(csn_compare(vucsn,deletedcsn)<0)
{
- if(!value_distinguished_at_csn(e, a, valuestoupdate[i], deletedcsn))
+ if(!value_distinguished_at_csn(e, a, valuestoupdate[i], deletedcsn))
{
entry_present_value_to_deleted_value(a,valuestoupdate[i]);
}
}
- valuestoupdate[i]->v_csnset = NULL;
- }
+ csnset_free(&valuestoupdate[i]->v_csnset);
+ }
}
}
diff --git a/ldap/servers/slapd/valueset.c b/ldap/servers/slapd/valueset.c
index fb7a99b..7b5fa01 100644
--- a/ldap/servers/slapd/valueset.c
+++ b/ldap/servers/slapd/valueset.c
@@ -1445,6 +1445,7 @@ valueset_update_csn_for_valuearray_ext(Slapi_ValueSet *vs, const Slapi_Attr *a,
{
value_update_csn(v,t,csn);
if (csnref_updated) {
+ csnset_free(&valuestoupdate[i]->v_csnset);
valuestoupdate[i]->v_csnset = csnset_dup(value_get_csnset(v));
}
valuearrayfast_add_value_passin(&vaf_valuesupdated,valuestoupdate[i]);
--
1.9.3