From 820abdb80a47e89f4d9460646513cc3d1bdf0706 Mon Sep 17 00:00:00 2001 From: Matthijs Mekking Date: Wed, 17 Jan 2024 16:53:27 +0100 Subject: [PATCH] Add proper qp cleanup Fix reference counting: unreference nodes that are succesfully inserted in the tree, detach created nodes, and cleanup the interior data in dns_qpdata_destroy(). --- lib/dns/qp-zonedb.c | 10 +++++++--- lib/dns/qpdb.c | 25 ++++++++++++++++++++++++- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/lib/dns/qp-zonedb.c b/lib/dns/qp-zonedb.c index f5a14a33ef..b545b506bf 100644 --- a/lib/dns/qp-zonedb.c +++ b/lib/dns/qp-zonedb.c @@ -1624,10 +1624,11 @@ loadnode(dns_qpdb_t *qpdb, const dns_name_t *name, dns_qpdata_t **nodep, } else { INSIST(nsecnode == NULL); nsecnode = dns_qpdata_create(qpdb, name); + nsecnode->nsec = DNS_DB_NSEC_NSEC; nsecresult = dns_qp_insert(qpdb->nsec, nsecnode, 0); INSIST(nsecresult == ISC_R_SUCCESS); + dns_qpdata_detach(&nsecnode); } - nsecnode->nsec = DNS_DB_NSEC_NSEC; node->nsec = DNS_DB_NSEC_HAS_NSEC; done: @@ -1695,6 +1696,7 @@ loading_addrdataset(void *arg, const dns_name_t *name, node = dns_qpdata_create(qpdb, name); result = dns_qp_insert(qpdb->nsec3, node, 0); INSIST(result == ISC_R_SUCCESS); + dns_qpdata_unref(node); } node->nsec = DNS_DB_NSEC_NSEC3; } else if (rdataset->type == dns_rdatatype_nsec) { @@ -2430,6 +2432,7 @@ dns__qpzone_wildcardmagic(dns_qpdb_t *qpdb, const dns_name_t *name, bool lock) { node = dns_qpdata_create(qpdb, &foundname); result = dns_qp_insert(qpdb->tree, node, 0); INSIST(result == ISC_R_SUCCESS); + dns_qpdata_unref(node); } INSIST(result == ISC_R_SUCCESS); @@ -2471,10 +2474,11 @@ dns__qpzone_addwildcards(dns_qpdb_t *qpdb, const dns_name_t *name, bool lock) { if (result != ISC_R_SUCCESS) { INSIST(node == NULL); node = dns_qpdata_create(qpdb, name); + node->nsec = DNS_DB_NSEC_NORMAL; result = dns_qp_insert(qpdb->tree, node, 0); INSIST(result == ISC_R_SUCCESS); - } - if (result == ISC_R_SUCCESS) { + dns_qpdata_detach(&node); + } else if (result == ISC_R_SUCCESS) { node->nsec = DNS_DB_NSEC_NORMAL; } } diff --git a/lib/dns/qpdb.c b/lib/dns/qpdb.c index 903356a3c4..b68b8ccf4d 100644 --- a/lib/dns/qpdb.c +++ b/lib/dns/qpdb.c @@ -600,6 +600,13 @@ dns__qpdb_destroy(dns_db_t *arg) { unsigned int i; unsigned int inactive = 0; + if (rbtdb->origin_node != NULL) { + dns_qpdata_detach(&rbtdb->origin_node); + } + if (rbtdb->nsec3_origin_node != NULL) { + dns_qpdata_detach(&rbtdb->nsec3_origin_node); + } + /* XXX check for open versions here */ if (qpdb->soanode != NULL) { @@ -1991,6 +1998,7 @@ dns__qpdb_findnodeintree(dns_qpdb_t *qpdb, dns_qp_t *tree, node = dns_qpdata_create(qpdb, name); result = dns_qp_insert(tree, node, 0); INSIST(result == ISC_R_SUCCESS); + dns_qpdata_unref(node); if (tree == qpdb->tree) { dns__qpzone_addwildcards(qpdb, name, true); @@ -3316,6 +3324,7 @@ dns__qpdb_addrdataset(dns_db_t *db, dns_dbnode_t *node, nsecnode->nsec = DNS_DB_NSEC_NSEC; result = dns_qp_insert(qpdb->nsec, nsecnode, 0); INSIST(result == ISC_R_SUCCESS); + dns_qpdata_detach(&nsecnode); } qpnode->nsec = DNS_DB_NSEC_HAS_NSEC; } @@ -4766,7 +4775,21 @@ dns_qpdata_create(dns_qpdb_t *qpdb, const dns_name_t *name) { void dns_qpdata_destroy(dns_qpdata_t *data) { - dns_name_free(data->name, data->mctx); + dns_slabheader_t *current = NULL, *next = NULL; + + for (current = data->data; current != NULL; current = next) { + dns_slabheader_t *down = current->down, *down_next = NULL; + + next = current->next; + + for (down = current->down; down != NULL; down = down_next) { + down_next = down->down; + dns_slabheader_destroy(&down); + } + + dns_slabheader_destroy(¤t); + } + isc_mem_putanddetach(&data->mctx, data, sizeof(dns_qpdata_t)); }