]> git.ipfire.org Git - thirdparty/ldns.git/commitdiff
Eliminate memory leaks
authorWillem Toorop <willem@nlnetlabs.nl>
Fri, 20 Nov 2020 13:48:19 +0000 (14:48 +0100)
committerWillem Toorop <willem@nlnetlabs.nl>
Fri, 20 Nov 2020 13:48:19 +0000 (14:48 +0100)
originally for the newly created ZONEMD RRs, but found a few other leaks while working on that

dnssec_sign.c
dnssec_zone.c
error.c
examples/ldns-signzone.c
examples/ldns-verify-zone.c
host2str.c
str2host.c
zone.c

index 07754b19f8d17ed0e0e833f8541e01d205acaae3..d68d0e2c23fbedf796753871550b81967586c080 100644 (file)
@@ -1368,8 +1368,8 @@ ldns_dnssec_zone_sign(ldns_dnssec_zone *zone,
        return ldns_dnssec_zone_sign_flg(zone, new_rrs, key_list, func, arg, 0);
 }
 
-ldns_status dnssec_zone_equip_zonemd(
-               ldns_dnssec_zone *zone, int flags, ldns_key_list *key_list);
+ldns_status dnssec_zone_equip_zonemd(ldns_dnssec_zone *zone,
+               ldns_rr_list *new_rrs, ldns_key_list *key_list, int flags);
 ldns_status
 ldns_dnssec_zone_sign_flg(ldns_dnssec_zone *zone,
                                  ldns_rr_list *new_rrs,
@@ -1430,7 +1430,7 @@ ldns_dnssec_zone_sign_flg(ldns_dnssec_zone *zone,
                *rrsets_ref = zonemd_rrset.next;
        }
        return flags & LDNS_SIGN_WITH_ZONEMD
-            ? dnssec_zone_equip_zonemd(zone, flags, key_list)
+            ? dnssec_zone_equip_zonemd(zone, new_rrs, key_list, flags)
             : result;
 }
 
@@ -1564,7 +1564,7 @@ ldns_dnssec_zone_sign_nsec3_flg_mkmap(ldns_dnssec_zone *zone,
                return result;
 
        return signflags & LDNS_SIGN_WITH_ZONEMD
-            ? dnssec_zone_equip_zonemd(zone, signflags, key_list)
+            ? dnssec_zone_equip_zonemd(zone, new_rrs, key_list, signflags)
             : result;
 }
 
index c307510dbcbf05465e27ad64dda16d793564cc75..809d73f43fc575a539ec83fbe17da5b595474529 100644 (file)
@@ -370,9 +370,10 @@ ldns_dnssec_name_free_internal(ldns_dnssec_name *name,
                        ldns_dnssec_rrs_free_internal(name->nsec_signatures, deep);
                }
                if (name->hashed_name) {
-                       if (deep) {
-                               ldns_rdf_deep_free(name->hashed_name);
-                       }
+                       /* Hashed name is always allocated when signing,
+                        * so always deep free
+                        */
+                       ldns_rdf_deep_free(name->hashed_name);
                }
                LDNS_FREE(name);
        }
@@ -793,10 +794,21 @@ ldns_dnssec_name_node_deep_free(ldns_rbnode_t *node, void *arg) {
        LDNS_FREE(node);
 }
 
+static void
+ldns_hashed_names_node_free(ldns_rbnode_t *node, void *arg) {
+       (void) arg;
+       LDNS_FREE(node);
+}
+
 void
 ldns_dnssec_zone_free(ldns_dnssec_zone *zone)
 {
        if (zone) {
+               if (zone->hashed_names) {
+                       ldns_traverse_postorder(zone->hashed_names,
+                                       ldns_hashed_names_node_free, NULL);
+                       LDNS_FREE(zone->hashed_names);
+               }
                if (zone->names) {
                        /* destroy all name structures within the tree */
                        ldns_traverse_postorder(zone->names,
@@ -812,6 +824,11 @@ void
 ldns_dnssec_zone_deep_free(ldns_dnssec_zone *zone)
 {
        if (zone) {
+               if (zone->hashed_names) {
+                       ldns_traverse_postorder(zone->hashed_names,
+                                       ldns_hashed_names_node_free, NULL);
+                       LDNS_FREE(zone->hashed_names);
+               }
                if (zone->names) {
                        /* destroy all name structures within the tree */
                        ldns_traverse_postorder(zone->names,
@@ -833,12 +850,6 @@ static void
 ldns_dnssec_name_make_hashed_name(ldns_dnssec_zone *zone,
                ldns_dnssec_name* name, ldns_rr* nsec3rr);
 
-static void
-ldns_hashed_names_node_free(ldns_rbnode_t *node, void *arg) {
-       (void) arg;
-       LDNS_FREE(node);
-}
-
 static void
 ldns_dnssec_zone_hashed_names_from_nsec3(
                ldns_dnssec_zone* zone, ldns_rr* nsec3rr)
@@ -908,20 +919,22 @@ ldns_dnssec_name_make_hashed_name(ldns_dnssec_zone *zone,
 static ldns_rbnode_t *
 ldns_dnssec_zone_find_nsec3_original(ldns_dnssec_zone *zone, ldns_rr *rr) {
        ldns_rdf *hashed_name;
+       ldns_rbnode_t *to_return;
 
-       hashed_name = ldns_dname_label(ldns_rr_owner(rr), 0);
-       if (hashed_name == NULL) {
-               return NULL;
-       }
        if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_NSEC3 && ! zone->_nsec3params){
 
                ldns_dnssec_zone_hashed_names_from_nsec3(zone, rr);
        }
        if (zone->hashed_names == NULL) {
-               ldns_rdf_deep_free(hashed_name);
                return NULL;
        }
-       return  ldns_rbtree_search(zone->hashed_names, hashed_name);
+       hashed_name = ldns_dname_label(ldns_rr_owner(rr), 0);
+       if (hashed_name == NULL) {
+               return NULL;
+       }
+       to_return = ldns_rbtree_search(zone->hashed_names, hashed_name);
+       ldns_rdf_deep_free(hashed_name);
+       return to_return;
 }
 
 ldns_status
@@ -1127,6 +1140,7 @@ ldns_dnssec_zone_add_empty_nonterminals_nsec3(
                                        }
                                        node = ldns_rbtree_search(nsec3s, 
                                                        ent_hashed_name);
+                                       ldns_rdf_deep_free(ent_hashed_name);
                                        if (!node) {
                                                ldns_rdf_deep_free(l1);
                                                ldns_rdf_deep_free(l2);
@@ -1205,34 +1219,6 @@ ldns_dnssec_zone_is_nsec3_optout(const ldns_dnssec_zone* zone)
 /*
  * Stuff for calculating and verifying zone digests
  */
-static ldns_status
-rr_list2dnssec_rrs(ldns_rr_list *rr_list, ldns_dnssec_rrs **rrs)
-{
-       ldns_rr *rr = NULL;
-
-       if (!rr_list || !rrs)
-               return LDNS_STATUS_NULL;
-
-       if (ldns_rr_list_rr_count(rr_list) == 0)
-               return LDNS_STATUS_OK;
-
-       if (!*rrs) {
-               if (!(*rrs = ldns_dnssec_rrs_new()))
-                       return LDNS_STATUS_MEM_ERR;
-               (*rrs)->rr = ldns_rr_list_pop_rr(rr_list);
-
-       }
-       while ((rr = ldns_rr_list_pop_rr(rr_list))) {
-               ldns_status st;
-              
-               if ((st = ldns_dnssec_rrs_add_rr(*rrs, rr))) {
-                       ldns_rr_list_push_rr(rr_list, rr);
-                       return st;
-               }
-       }
-       return LDNS_STATUS_OK;
-}
-
 typedef enum dnssec_zone_rr_iter_state {
          DNSSEC_ZONE_RR_ITER_LT_RRSIG
        , DNSSEC_ZONE_RR_ITER_RRSIGs_NO_NSEC
@@ -1783,9 +1769,41 @@ ldns_dnssec_zone_verify_zonemd(ldns_dnssec_zone *zone)
 }
 
 #ifdef HAVE_SSL
+static ldns_status
+rr_list2dnssec_rrs(ldns_rr_list *rr_list, ldns_dnssec_rrs **rrs,
+               ldns_rr_list *new_rrs)
+{
+       ldns_rr *rr = NULL;
+
+       if (!rr_list || !rrs)
+               return LDNS_STATUS_NULL;
+
+       if (ldns_rr_list_rr_count(rr_list) == 0)
+               return LDNS_STATUS_OK;
+
+       if (!*rrs) {
+               if (!(*rrs = ldns_dnssec_rrs_new()))
+                       return LDNS_STATUS_MEM_ERR;
+               (*rrs)->rr = ldns_rr_list_pop_rr(rr_list);
+               if (new_rrs)
+                       ldns_rr_list_push_rr(new_rrs, (*rrs)->rr);
+       }
+       while ((rr = ldns_rr_list_pop_rr(rr_list))) {
+               ldns_status st;
+              
+               if ((st = ldns_dnssec_rrs_add_rr(*rrs, rr))) {
+                       ldns_rr_list_push_rr(rr_list, rr);
+                       return st;
+               } else if (new_rrs)
+                       ldns_rr_list_push_rr(new_rrs, rr);
+       }
+       return LDNS_STATUS_OK;
+}
+
+
 ldns_status
-dnssec_zone_equip_zonemd(
-               ldns_dnssec_zone *zone, int signflags, ldns_key_list *key_list)
+dnssec_zone_equip_zonemd(ldns_dnssec_zone *zone,
+               ldns_rr_list *new_rrs, ldns_key_list *key_list, int signflags)
 {
        ldns_status st = LDNS_STATUS_OK;
        zone_digester zd;
@@ -1841,9 +1859,10 @@ dnssec_zone_equip_zonemd(
        }
        if ((zonemd_rrsigs = ldns_sign_public(zonemd_rr_list, key_list)))
                st = rr_list2dnssec_rrs(  zonemd_rrsigs
-                                      , &zonemd_rrset->signatures);
+                                      , &zonemd_rrset->signatures, new_rrs);
        if (!st)
-               st = rr_list2dnssec_rrs(zonemd_rr_list, &zonemd_rrset->rrs);
+               st = rr_list2dnssec_rrs(  zonemd_rr_list
+                                      , &zonemd_rrset->rrs, new_rrs);
        ldns_rr_list_deep_free(zonemd_rr_list);
        ldns_rr_list_deep_free(zonemd_rrsigs);
        return st;
diff --git a/error.c b/error.c
index 29e167e33fdd6b4466b3eb857262672d0cf643b8..60a76d551f31366eb7d7a9d82ce8818eaae9538a 100644 (file)
--- a/error.c
+++ b/error.c
@@ -162,8 +162,8 @@ ldns_lookup_table ldns_error_str[] = {
        { LDNS_STATUS_ZONEMD_INVALID_SOA,
                "Missing or invalid SOA to associate with ZONEMD RR" },
        { LDNS_STATUS_NO_ZONEMD,
-               "NSEC and NSEC3 RRs say that ZONEMD exists, "
-               "but it is not present in the zone" },
+               "NSEC(3) RRs indicate that a ZONEMD exists, "
+               "but it is not found in the zone" },
        { LDNS_STATUS_NO_VALID_ZONEMD,
                "No ZONEMD matching the zone data was found" },
        { 0, NULL }
index 0b17ea7ad7da671cf7d840b7a9f8c2fcc4702d80..d383b9e4e27f5b34f1bd1ffa73ff13e10a246c8e 100644 (file)
@@ -1097,7 +1097,7 @@ main(int argc, char *argv[])
        ldns_dnssec_zone_free(signed_zone);
        ldns_zone_deep_free(orig_zone);
        ldns_rr_list_deep_free(added_rrs);
-       
+       ldns_rdf_deep_free(origin);
        LDNS_FREE(outputfile_name);
 
 #ifndef OPENSSL_NO_ENGINE
index 68534d00c7a6c16e97bffab6be0693fd4d8b57bf..4acfacddacb1ada2ee2c9160dff8b420de32c436 100644 (file)
@@ -924,9 +924,17 @@ main(int argc, char **argv)
 
                if (!result) {
                        result = ldns_dnssec_zone_verify_zonemd(dnssec_zone);
-                       if (result && verbosity > 3) {
-                               fprintf(myerr,
-                                       "Could not validate zone digest\n");
+                       if (verbosity > 3) {
+                               if (result)
+                                       fprintf( myerr
+                                              , "Could not validate"
+                                                " zone digest: %s\n"
+                                              , ldns_get_errorstr_by_id(
+                                                      result));
+                               else
+                                       fprintf( myout
+                                              , "Zone digest matched"
+                                                " the zone content\n");
                        }
                }
                if (result == LDNS_STATUS_OK) {
index d8108db0c8bfa5de020f0776a33fb04fe974f41a..77a6ba7eda8d6d4bacc9e5239d58ed9b4a129606 100644 (file)
@@ -1764,7 +1764,7 @@ ldns_rr2buffer_str_fmt(ldns_buffer *output,
                                                           node->data
                                                        ));
                                        }
-                                       ldns_rdf_free(key);
+                                       ldns_rdf_deep_free(key);
                                }
                                key = ldns_b32_ext2dname(
                                                ldns_nsec3_next_owner(rr));
@@ -1782,7 +1782,7 @@ ldns_rr2buffer_str_fmt(ldns_buffer *output,
                                                           node->data
                                                        ));
                                        }
-                                       ldns_rdf_free(key);
+                                       ldns_rdf_deep_free(key);
                                }
                        }
                        ldns_buffer_printf(output, "}");
index 40af30519e2e79eb568212fba9b7813d4de12748..0837acf96c67e4f522d7c1a400b6b02d8415e7d5 100644 (file)
@@ -1415,8 +1415,8 @@ ldns_str2rdf_ipseckey(ldns_rdf **rd, const char *str)
                LDNS_FREE(publickey);
        LDNS_FREE(token);
        ldns_buffer_free(str_buf);
-       ldns_rdf_free(gateway_rdf);
-       ldns_rdf_free(publickey_rdf);
+       ldns_rdf_deep_free(gateway_rdf);
+       ldns_rdf_deep_free(publickey_rdf);
        LDNS_FREE(data);
        if(!*rd) return LDNS_STATUS_MEM_ERR;
        return LDNS_STATUS_OK;
diff --git a/zone.c b/zone.c
index e95207482354a6e8ba89759b11ce58c9dcd00818..0d12a7c7f5e8f6275b9b6d001f655f246e70682b 100644 (file)
--- a/zone.c
+++ b/zone.c
@@ -245,7 +245,11 @@ ldns_zone_new_frm_fp_l(ldns_zone **z, FILE *fp, const ldns_rdf *origin, uint32_t
                        }
                        
                        /* a normal RR - as sofar the DNS is normal */
-                       if (!ldns_zone_push_rr(newzone, rr)) goto error;
+                       if (!ldns_zone_push_rr(newzone, rr)) {
+                               ldns_rr_free(rr);
+                               goto error;
+                       }
+                       break;
 
                case LDNS_STATUS_SYNTAX_EMPTY:
                        /* empty line was seen */