diff options
author | Nathan Kinder <nkinder@boraras.localdomain> | 2009-07-30 16:52:26 -0700 |
---|---|---|
committer | Nathan Kinder <nkinder@boraras.localdomain> | 2009-07-30 16:52:26 -0700 |
commit | b1c7eacf47f7e068260fac7d3c372d3fcb82f82a (patch) | |
tree | 9c270c607abe24dbb9e985fdc82d57924e253f40 /ldap/servers | |
parent | 7a4fce4d5e9d194962eeb7c7c780376a3b5ed130 (diff) | |
download | ds-b1c7eacf47f7e068260fac7d3c372d3fcb82f82a.tar.gz ds-b1c7eacf47f7e068260fac7d3c372d3fcb82f82a.tar.xz ds-b1c7eacf47f7e068260fac7d3c372d3fcb82f82a.zip |
Bug 514824: Fix double free in macro ACI code.
If you have an ACI with multiple macros in it and the second attribtue does not
exist in the entry you are bound as, the in-memory list used for macro
substitution is free'd twice.
The code swaps hands the charray it plans to return after substitution over to
a working list, but it doesn't set the return list to NULL. When the second
macro attribute is not found, the working list is free'd, yet the address is
returned to the caller, who then tries to free the list a second time. The fix
is to set the list to be returned to NULL when the memory is handed over to the
working list.
Diffstat (limited to 'ldap/servers')
-rw-r--r-- | ldap/servers/plugins/acl/acllas.c | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/ldap/servers/plugins/acl/acllas.c b/ldap/servers/plugins/acl/acllas.c index e16fbd27..d2205968 100644 --- a/ldap/servers/plugins/acl/acllas.c +++ b/ldap/servers/plugins/acl/acllas.c @@ -4025,7 +4025,6 @@ acllas_replace_attr_macro( char *rule, lasInfo *lasinfo) { int i, j; char *patched_rule; - a = NULL; i= slapi_attr_first_value ( attr, &sval ); while(i != -1) { attrValue = slapi_value_get_berval(sval); @@ -4045,12 +4044,23 @@ acllas_replace_attr_macro( char *rule, lasInfo *lasinfo) { /* * Here, a is working_list, where each member has had - * macro_str replaced with attrVal. - */ + * macro_str replaced with attrVal. We hand a over, + * so we must set it to NULL since the working list + * may be free'd later. */ charray_free(working_list); - working_list = a; - working_rule = a[0]; + if (a == NULL) { + /* This shouldn't happen, but we play + * if safe to avoid any problems. */ + slapi_ch_free((void **)¯o_str); + slapi_ch_free((void **)¯o_attr_name); + charray_add(&a, slapi_ch_strdup("")); + return(a); + } else { + working_list = a; + working_rule = a[0]; + a = NULL; + } } slapi_ch_free((void **)¯o_str); slapi_ch_free((void **)¯o_attr_name); |