mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-30 05:57:52 +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:
parent
7db974b240
commit
3facc5b51d
@ -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.
|
||||
*/
|
||||
TREE_FORCEUPGRADE(&qpdb->tree_lock, &tlocktype);
|
||||
node = dns_qpdata_create(qpdb, name);
|
||||
result = dns_qp_insert(tree, node, 0);
|
||||
INSIST(result == ISC_R_SUCCESS);
|
||||
dns_qpdata_unref(node);
|
||||
result = dns_qp_lookup(tree, name, NULL, NULL, NULL,
|
||||
(void **)&node, NULL);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user