2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-09-04 08:35:31 +00:00

3688. [bug] loadnode could return a freed node on out of memory.

[RT #35106]
This commit is contained in:
Mark Andrews
2013-12-12 12:49:44 +11:00
parent 3f9791eac4
commit e4d0018d4c
2 changed files with 62 additions and 28 deletions

View File

@@ -1,3 +1,6 @@
3688. [bug] loadnode could return a freed node on out of memory.
[RT #35106]
3687. [bug] Address null pointer dereference in zone_xfrdone. 3687. [bug] Address null pointer dereference in zone_xfrdone.
[RT #35042] [RT #35042]

View File

@@ -6834,27 +6834,42 @@ static isc_result_t
loadnode(dns_rbtdb_t *rbtdb, dns_name_t *name, dns_rbtnode_t **nodep, loadnode(dns_rbtdb_t *rbtdb, dns_name_t *name, dns_rbtnode_t **nodep,
isc_boolean_t hasnsec) isc_boolean_t hasnsec)
{ {
isc_result_t noderesult, nsecresult; isc_result_t noderesult, nsecresult, tmpresult;
dns_rbtnode_t *nsecnode; dns_rbtnode_t *nsecnode = NULL, *node = NULL;
noderesult = dns_rbt_addnode(rbtdb->tree, name, nodep); noderesult = dns_rbt_addnode(rbtdb->tree, name, &node);
if (rbtdb->rpzs != NULL && noderesult == ISC_R_SUCCESS) {
if (rbtdb->rpzs != NULL && noderesult == ISC_R_SUCCESS)
noderesult = dns_rpz_add(rbtdb->load_rpzs, rbtdb->rpz_num, noderesult = dns_rpz_add(rbtdb->load_rpzs, rbtdb->rpz_num,
name); name);
if (noderesult != ISC_R_SUCCESS) {
/*
* Remove the node we just added above.
*/
tmpresult = dns_rbt_deletenode(rbtdb->tree, node,
ISC_FALSE);
if (tmpresult != ISC_R_SUCCESS)
isc_log_write(dns_lctx,
DNS_LOGCATEGORY_DATABASE,
DNS_LOGMODULE_CACHE,
ISC_LOG_WARNING,
"loading_addrdataset: "
"dns_rbt_deletenode: %s after "
"dns_rbt_addnode(NSEC): %s",
isc_result_totext(tmpresult),
isc_result_totext(ISC_R_SUCCESS));
}
}
if (!hasnsec) if (!hasnsec)
return (noderesult); goto done;
if (noderesult == ISC_R_EXISTS) { if (noderesult == ISC_R_EXISTS) {
/* /*
* Add a node to the auxiliary NSEC tree for an old node * Add a node to the auxiliary NSEC tree for an old node
* just now getting an NSEC record. * just now getting an NSEC record.
*/ */
if ((*nodep)->nsec == DNS_RBT_NSEC_HAS_NSEC) if (node->nsec == DNS_RBT_NSEC_HAS_NSEC)
return (noderesult); goto done;
} else if (noderesult != ISC_R_SUCCESS) { } else if (noderesult != ISC_R_SUCCESS)
return (noderesult); goto done;
}
/* /*
* Build the auxiliary tree for NSECs as we go. * Build the auxiliary tree for NSECs as we go.
@@ -6864,12 +6879,11 @@ loadnode(dns_rbtdb_t *rbtdb, dns_name_t *name, dns_rbtnode_t **nodep,
* Add nodes to the auxiliary tree after corresponding nodes have * Add nodes to the auxiliary tree after corresponding nodes have
* been added to the main tree. * been added to the main tree.
*/ */
nsecnode = NULL;
nsecresult = dns_rbt_addnode(rbtdb->nsec, name, &nsecnode); nsecresult = dns_rbt_addnode(rbtdb->nsec, name, &nsecnode);
if (nsecresult == ISC_R_SUCCESS) { if (nsecresult == ISC_R_SUCCESS) {
nsecnode->nsec = DNS_RBT_NSEC_NSEC; nsecnode->nsec = DNS_RBT_NSEC_NSEC;
(*nodep)->nsec = DNS_RBT_NSEC_HAS_NSEC; node->nsec = DNS_RBT_NSEC_HAS_NSEC;
return (noderesult); goto done;
} }
if (nsecresult == ISC_R_EXISTS) { if (nsecresult == ISC_R_EXISTS) {
@@ -6880,21 +6894,38 @@ loadnode(dns_rbtdb_t *rbtdb, dns_name_t *name, dns_rbtnode_t **nodep,
ISC_LOG_WARNING, ISC_LOG_WARNING,
"addnode: NSEC node already exists"); "addnode: NSEC node already exists");
#endif #endif
(*nodep)->nsec = DNS_RBT_NSEC_HAS_NSEC; node->nsec = DNS_RBT_NSEC_HAS_NSEC;
return (noderesult); goto done;
} }
nsecresult = dns_rbt_deletenode(rbtdb->tree, *nodep, ISC_FALSE); if (noderesult == ISC_R_SUCCESS) {
if (nsecresult != ISC_R_SUCCESS) /*
isc_log_write(dns_lctx, * Remove the node we just added above.
DNS_LOGCATEGORY_DATABASE, */
DNS_LOGMODULE_CACHE, tmpresult = dns_rbt_deletenode(rbtdb->tree, node, ISC_FALSE);
ISC_LOG_WARNING, if (tmpresult != ISC_R_SUCCESS)
"loading_addrdataset: " isc_log_write(dns_lctx,
"dns_rbt_deletenode: %s after " DNS_LOGCATEGORY_DATABASE,
"dns_rbt_addnode(NSEC): %s", DNS_LOGMODULE_CACHE,
isc_result_totext(nsecresult), ISC_LOG_WARNING,
isc_result_totext(noderesult)); "loading_addrdataset: "
"dns_rbt_deletenode: %s after "
"dns_rbt_addnode(NSEC): %s",
isc_result_totext(tmpresult),
isc_result_totext(noderesult));
if (rbtdb->rpzs != NULL && noderesult == ISC_R_SUCCESS)
dns_rpz_delete(rbtdb->rpzs, rbtdb->rpz_num, name);
}
/*
* Set the error condition to be returned.
*/
noderesult = nsecresult;
done:
if (noderesult == ISC_R_SUCCESS || noderesult == ISC_R_EXISTS)
*nodep = node;
return (noderesult); return (noderesult);
} }