diff --git a/CHANGES b/CHANGES index ea77e3bf60..760c5de8aa 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,7 @@ --- 9.5.0a7 released --- +2252. [bug] Fixed memory leaks in sortlist code [RT #17216] + 2251. [placeholder] 2250. [func] New flag 'memstatistics' to state whether the diff --git a/lib/isccfg/aclconf.c b/lib/isccfg/aclconf.c index 616ec1a810..bdb4bb0f22 100644 --- a/lib/isccfg/aclconf.c +++ b/lib/isccfg/aclconf.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: aclconf.c,v 1.11 2007/09/14 01:46:05 marka Exp $ */ +/* $Id: aclconf.c,v 1.12 2007/10/12 04:17:18 each Exp $ */ #include @@ -81,7 +81,7 @@ get_acl_def(const cfg_obj_t *cctx, const char *name, const cfg_obj_t **ret) { static isc_result_t convert_named_acl(const cfg_obj_t *nameobj, const cfg_obj_t *cctx, isc_log_t *lctx, cfg_aclconfctx_t *ctx, - isc_mem_t *mctx, int nest_level, + isc_mem_t *mctx, unsigned int nest_level, dns_acl_t **target) { isc_result_t result; @@ -166,7 +166,7 @@ cfg_acl_fromconfig(const cfg_obj_t *caml, isc_log_t *lctx, cfg_aclconfctx_t *ctx, isc_mem_t *mctx, - int nest_level, + unsigned int nest_level, dns_acl_t **target) { isc_result_t result; @@ -185,7 +185,8 @@ cfg_acl_fromconfig(const cfg_obj_t *caml, * nested ACL's contents should just be absorbed into its * parent ACL. */ - dacl = *target; + dns_acl_attach(*target, &dacl); + dns_acl_detach(target); } else { /* * Need to allocate a new ACL structure. Count the items @@ -193,7 +194,10 @@ cfg_acl_fromconfig(const cfg_obj_t *caml, * elements (even though some or all of them may end up in * the iptable instead of the element array). */ - result = dns_acl_create(mctx, cfg_list_length(caml), &dacl); + isc_boolean_t recurse = ISC_TF(nest_level == 0); + result = dns_acl_create(mctx, + cfg_list_length(caml, recurse), + &dacl); if (result != ISC_R_SUCCESS) return (result); } @@ -219,8 +223,10 @@ cfg_acl_fromconfig(const cfg_obj_t *caml, * merged into the main iptable. */ iptab = dacl->iptable; - if (nest_level > 0) { - result = dns_acl_create(mctx, cfg_list_length(ce), + + if (nest_level != 0) { + result = dns_acl_create(mctx, + cfg_list_length(ce, ISC_FALSE), &de->nestedacl); if (result != ISC_R_SUCCESS) goto cleanup; @@ -238,7 +244,7 @@ cfg_acl_fromconfig(const cfg_obj_t *caml, if (result != ISC_R_SUCCESS) goto cleanup; - if (nest_level > 0) { + if (nest_level != 0) { /* This prefix is going into a nested acl */ de->type = dns_aclelementtype_nestedacl; de->negative = neg; @@ -300,10 +306,11 @@ cfg_acl_fromconfig(const cfg_obj_t *caml, result = get_acl_def(cctx, name, NULL); if (result == ISC_R_SUCCESS) { /* found it in acl definitions */ - inneracl = NULL; + if (inneracl != NULL) + dns_acl_detach(&inneracl); result = convert_named_acl(ce, cctx, lctx, ctx, mctx, - (nest_level > 0) + (nest_level != 0) ? (nest_level - 1) : 0, &inneracl); @@ -311,16 +318,21 @@ cfg_acl_fromconfig(const cfg_obj_t *caml, if (result != ISC_R_SUCCESS) goto cleanup; - if (nest_level) { - de->type = dns_aclelementtype_nestedacl, + if (nest_level != 0) { + de->type = dns_aclelementtype_nestedacl; de->negative = neg; - de->nestedacl = inneracl; + if(de->nestedacl != NULL) + dns_acl_detach(&de->nestedacl); + dns_acl_attach(inneracl, + &de->nestedacl); + dns_acl_detach(&inneracl); + /* Fall through */ } else { dns_acl_merge(dacl, inneracl, ISC_TF(!neg)); dns_acl_detach(&inneracl); + continue; } - continue; } } else { cfg_obj_log(ce, lctx, ISC_LOG_WARNING, @@ -335,7 +347,8 @@ cfg_acl_fromconfig(const cfg_obj_t *caml, * and keyname elements, and nested ACLs if nest_level is * nonzero (i.e., in sortlists). */ - if (nest_level > 0 && de->type != dns_aclelementtype_nestedacl) + if (de->nestedacl != NULL && + de->type != dns_aclelementtype_nestedacl) dns_acl_detach(&de->nestedacl); dacl->node_count++; @@ -346,10 +359,12 @@ cfg_acl_fromconfig(const cfg_obj_t *caml, INSIST(dacl->length <= dacl->alloc); } - *target = dacl; - return (ISC_R_SUCCESS); + dns_acl_attach(dacl, target); + result = ISC_R_SUCCESS; cleanup: + if (inneracl != NULL) + dns_acl_detach(&inneracl); dns_acl_detach(&dacl); return (result); } diff --git a/lib/isccfg/include/isccfg/aclconf.h b/lib/isccfg/include/isccfg/aclconf.h index 778a19c45b..7ad4351f34 100644 --- a/lib/isccfg/include/isccfg/aclconf.h +++ b/lib/isccfg/include/isccfg/aclconf.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: aclconf.h,v 1.9 2007/09/12 01:09:08 each Exp $ */ +/* $Id: aclconf.h,v 1.10 2007/10/12 04:17:18 each Exp $ */ #ifndef ISCCFG_ACLCONF_H #define ISCCFG_ACLCONF_H 1 @@ -55,7 +55,7 @@ cfg_acl_fromconfig(const cfg_obj_t *caml, isc_log_t *lctx, cfg_aclconfctx_t *ctx, isc_mem_t *mctx, - int nest_level, + unsigned int nest_level, dns_acl_t **target); /* * Construct a new dns_acl_t from configuration data in 'caml' and diff --git a/lib/isccfg/include/isccfg/cfg.h b/lib/isccfg/include/isccfg/cfg.h index 79133931cf..d0ed94b8f6 100644 --- a/lib/isccfg/include/isccfg/cfg.h +++ b/lib/isccfg/include/isccfg/cfg.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: cfg.h,v 1.43 2007/09/14 01:46:06 marka Exp $ */ +/* $Id: cfg.h,v 1.44 2007/10/12 04:17:18 each Exp $ */ #ifndef ISCCFG_CFG_H #define ISCCFG_CFG_H 1 @@ -348,10 +348,11 @@ cfg_list_next(const cfg_listelt_t *elt); */ unsigned int -cfg_list_length(const cfg_obj_t *obj); +cfg_list_length(const cfg_obj_t *obj, isc_boolean_t recurse); /*%< * Returns the length of a list of configure objects. If obj is - * not a list, returns 0. + * not a list, returns 0. If recurse is true, add in the length of + * all contained lists. */ const cfg_obj_t * diff --git a/lib/isccfg/parser.c b/lib/isccfg/parser.c index a22307eecd..79c7c48914 100644 --- a/lib/isccfg/parser.c +++ b/lib/isccfg/parser.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: parser.c,v 1.126 2007/09/14 01:46:05 marka Exp $ */ +/* $Id: parser.c,v 1.127 2007/10/12 04:17:18 each Exp $ */ /*! \file */ @@ -1114,16 +1114,20 @@ cfg_list_next(const cfg_listelt_t *elt) { * a list, return 0. */ unsigned int -cfg_list_length(const cfg_obj_t *obj) { +cfg_list_length(const cfg_obj_t *obj, isc_boolean_t recurse) { const cfg_listelt_t *elt; unsigned int count = 0; - if (obj == NULL || ! cfg_obj_islist(obj)) + if (obj == NULL || !cfg_obj_islist(obj)) return (0U); for (elt = cfg_list_first(obj); elt != NULL; elt = cfg_list_next(elt)) { - count++; + if (recurse && cfg_obj_islist(elt->obj)) { + count += cfg_list_length(elt->obj, recurse); + } else { + count++; + } } return (count); }