From: Willem Toorop Date: Fri, 20 Nov 2020 13:48:19 +0000 (+0100) Subject: Eliminate memory leaks X-Git-Tag: 1.8.0-rc.1~45^2~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=90a870782646e99aee66c766e2f4dbea10ddd205;p=thirdparty%2Fldns.git Eliminate memory leaks originally for the newly created ZONEMD RRs, but found a few other leaks while working on that --- diff --git a/dnssec_sign.c b/dnssec_sign.c index 07754b19..d68d0e2c 100644 --- a/dnssec_sign.c +++ b/dnssec_sign.c @@ -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; } diff --git a/dnssec_zone.c b/dnssec_zone.c index c307510d..809d73f4 100644 --- a/dnssec_zone.c +++ b/dnssec_zone.c @@ -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 29e167e3..60a76d55 100644 --- 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 } diff --git a/examples/ldns-signzone.c b/examples/ldns-signzone.c index 0b17ea7a..d383b9e4 100644 --- a/examples/ldns-signzone.c +++ b/examples/ldns-signzone.c @@ -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 diff --git a/examples/ldns-verify-zone.c b/examples/ldns-verify-zone.c index 68534d00..4acfacdd 100644 --- a/examples/ldns-verify-zone.c +++ b/examples/ldns-verify-zone.c @@ -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) { diff --git a/host2str.c b/host2str.c index d8108db0..77a6ba7e 100644 --- a/host2str.c +++ b/host2str.c @@ -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, "}"); diff --git a/str2host.c b/str2host.c index 40af3051..0837acf9 100644 --- a/str2host.c +++ b/str2host.c @@ -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 e9520748..0d12a7c7 100644 --- 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 */