]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Fixed some memory management problems in sortlist code [rt17216]
authorEvan Hunt <each@isc.org>
Fri, 12 Oct 2007 04:17:18 +0000 (04:17 +0000)
committerEvan Hunt <each@isc.org>
Fri, 12 Oct 2007 04:17:18 +0000 (04:17 +0000)
CHANGES
lib/isccfg/aclconf.c
lib/isccfg/include/isccfg/aclconf.h
lib/isccfg/include/isccfg/cfg.h
lib/isccfg/parser.c

diff --git a/CHANGES b/CHANGES
index ea77e3bf60f1e2f25fcf795f43b8cf24fa1b9745..760c5de8aa50d950001e061e6b8ff1f8a10e1a31 100644 (file)
--- 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
index 616ec1a8102453c8673fb056f102cfd117403a8b..bdb4bb0f2274f26c6856e310e731e02c59b1ebce 100644 (file)
@@ -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 <config.h>
 
@@ -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);
 }
index 778a19c45b1e508a4956db43443f9ebaa50de1b2..7ad4351f343594523473701e4c4498a89606c6cd 100644 (file)
@@ -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
index 79133931cf79ed679948f41f162ef5ddb5be0803..d0ed94b8f655d81fca0d2655abce5bda99618868 100644 (file)
@@ -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 *
index a22307eecd19e569ce32301af0cd9e130cb4a863..79c7c48914baa80ff7a612a59de729817f4cd53b 100644 (file)
@@ -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);
 }