2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-31 14:35:26 +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.
[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,
isc_boolean_t hasnsec)
{
isc_result_t noderesult, nsecresult;
dns_rbtnode_t *nsecnode;
isc_result_t noderesult, nsecresult, tmpresult;
dns_rbtnode_t *nsecnode = NULL, *node = NULL;
noderesult = dns_rbt_addnode(rbtdb->tree, name, nodep);
if (rbtdb->rpzs != NULL && noderesult == ISC_R_SUCCESS)
noderesult = dns_rbt_addnode(rbtdb->tree, name, &node);
if (rbtdb->rpzs != NULL && noderesult == ISC_R_SUCCESS) {
noderesult = dns_rpz_add(rbtdb->load_rpzs, rbtdb->rpz_num,
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)
return (noderesult);
goto done;
if (noderesult == ISC_R_EXISTS) {
/*
* Add a node to the auxiliary NSEC tree for an old node
* just now getting an NSEC record.
*/
if ((*nodep)->nsec == DNS_RBT_NSEC_HAS_NSEC)
return (noderesult);
} else if (noderesult != ISC_R_SUCCESS) {
return (noderesult);
}
if (node->nsec == DNS_RBT_NSEC_HAS_NSEC)
goto done;
} else if (noderesult != ISC_R_SUCCESS)
goto done;
/*
* 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
* been added to the main tree.
*/
nsecnode = NULL;
nsecresult = dns_rbt_addnode(rbtdb->nsec, name, &nsecnode);
if (nsecresult == ISC_R_SUCCESS) {
nsecnode->nsec = DNS_RBT_NSEC_NSEC;
(*nodep)->nsec = DNS_RBT_NSEC_HAS_NSEC;
return (noderesult);
node->nsec = DNS_RBT_NSEC_HAS_NSEC;
goto done;
}
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,
"addnode: NSEC node already exists");
#endif
(*nodep)->nsec = DNS_RBT_NSEC_HAS_NSEC;
return (noderesult);
node->nsec = DNS_RBT_NSEC_HAS_NSEC;
goto done;
}
nsecresult = dns_rbt_deletenode(rbtdb->tree, *nodep, ISC_FALSE);
if (nsecresult != 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(nsecresult),
isc_result_totext(noderesult));
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(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);
}