ldap/servers/slapd/attrlist.c | 22 +++++++++++++++++++---
1 file changed, 19 insertions(+), 3 deletions(-)
New commits:
commit 783fb90818c55940283a2c135a7bce4b77432d95
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Thu Jul 24 10:48:23 2014 -0700
Ticket #346 - Fixing memory leaks
Description:
There was a leak in attrlist_replace/attrlist_replace_with_flags
when attr_replace failed to replace the attribute values.
commit 708a56b8d524131362e2d71b7fbc2eb257075e14 for Ticket #47834
tried to fix it, but it was wrong and introduced a double free.
This patch fixes it so that ...
If attr_replace fails and if to be replaced Slapi_Attr is newly
created in attrlist_replace//attrlist_replace_with_flags, the
Slapi_Attr is removed from the attrlist (alist) and Slapi_Attr
is freed. Otherwise, values and Slapi_Attr are not freed since
Slapi_Attr is just pointing the attribute in the attrlist and
values are consumed in attr_replace.
https://fedorahosted.org/389/ticket/346
Reviewed by rmeggins(a)redhat.com (Thank you, Rich!!)
(cherry picked from commit c9b914b1610f6c03af4bcae9d311186807220068)
(cherry picked from commit b393c360499d001f0dd08de4d77d27a4e4f3048a)
(cherry picked from commit 3777f9c71bc53595d4d62a500da7a2897d056267)
diff --git a/ldap/servers/slapd/attrlist.c b/ldap/servers/slapd/attrlist.c
index cedf9ea..4b89dcc 100644
--- a/ldap/servers/slapd/attrlist.c
+++ b/ldap/servers/slapd/attrlist.c
@@ -288,13 +288,21 @@ int attrlist_replace(Slapi_Attr **alist, const char *type, struct
berval **vals)
if (vals == NULL || vals[0] == NULL) {
(void)attrlist_delete(alist, type);
} else {
- attrlist_find_or_create(alist, type, &a);
+ int created = attrlist_find_or_create(alist, type, &a);
valuearray_init_bervalarray(vals, &values);
if (slapi_attr_is_dn_syntax_attr(*a)) {
valuearray_dn_normalize_value(values);
(*a)->a_flags |= SLAPI_ATTR_FLAG_NORMALIZED_CES;
}
- rc = attr_replace(*a, values);
+ rc = attr_replace(*a, values); /* values is consumed */
+ if (rc) {
+ slapi_log_error(SLAPI_LOG_FATAL, "attrlist_replace",
+ "attr_replace (%s, %s) failed.\n",
+ type, vals[0]->bv_val);
+ if (created) {
+ attrlist_delete(alist, type);
+ }
+ }
}
return rc;
}
@@ -315,13 +323,21 @@ int attrlist_replace_with_flags(Slapi_Attr **alist, const char
*type, struct ber
if (vals == NULL || vals[0] == NULL) {
(void)attrlist_delete(alist, type);
} else {
- attrlist_find_or_create(alist, type, &a);
+ int created = attrlist_find_or_create(alist, type, &a);
valuearray_init_bervalarray_with_flags(vals, &values, flags);
if (slapi_attr_is_dn_syntax_attr(*a)) {
valuearray_dn_normalize_value(values);
(*a)->a_flags |= SLAPI_ATTR_FLAG_NORMALIZED_CES;
}
rc = attr_replace(*a, values);
+ if (rc) {
+ slapi_log_error(SLAPI_LOG_FATAL, "attrlist_replace",
+ "attr_replace (%s, %s) failed.\n",
+ type, vals[0]->bv_val);
+ if (created) {
+ attrlist_delete(alist, type);
+ }
+ }
}
return rc;
}