2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-30 14:07:59 +00:00

Fix race condition crash

When running resolver benchmark pipeline, a crash occurred:

https://gitlab.isc.org/isc-projects/bind9-shotgun-ci/-/pipelines/163946

In the code we are doing a lookup, it fails (meaning there is no node
with lookup name), we create the node and insert it and it fails.
But dns_qp_insert can only return ISC_R_SUCCESS or ISC_R_EXISTS.
So it must have been inserted in between. This is a race condition bug.

The first lookup only requires a write lock and if the lookup failed
the lock gets upgraded to a write lock and we insert the missing data.

To fix the race condition bug, we need to do a lookup again after we
have upgraded the lock to make sure it wasn't inserted in the mean
time.
This commit is contained in:
Matthijs Mekking
2024-02-19 12:05:34 +01:00
parent 7db974b240
commit 3facc5b51d

View File

@@ -1905,10 +1905,14 @@ dns__qpdb_findnodeintree(dns_qpdb_t *qpdb, dns_qp_t *tree,
* Try to upgrade the lock and if that fails unlock then relock. * Try to upgrade the lock and if that fails unlock then relock.
*/ */
TREE_FORCEUPGRADE(&qpdb->tree_lock, &tlocktype); TREE_FORCEUPGRADE(&qpdb->tree_lock, &tlocktype);
node = dns_qpdata_create(qpdb, name); result = dns_qp_lookup(tree, name, NULL, NULL, NULL,
result = dns_qp_insert(tree, node, 0); (void **)&node, NULL);
INSIST(result == ISC_R_SUCCESS); if (result != ISC_R_SUCCESS) {
dns_qpdata_unref(node); 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) { if (tree == qpdb->tree) {
dns__qpzone_addwildcards(qpdb, name, true); dns__qpzone_addwildcards(qpdb, name, true);