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:
3
CHANGES
3
CHANGES
@@ -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]
|
||||||
|
|
||||||
|
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user