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