Commit 06021b35 authored by Witold Krecicki's avatar Witold Krecicki Committed by Evan Hunt
Browse files

Fix deadlock in RPZ update code.

In dns_rpz_update_from_db we call setup_update which creates the db
iterator and calls dns_dbiterator_first. This unpauses the iterator and
might cause db->tree_lock to be acquired. We then do isc_task_send(...)
on an event to do quantum_update, which (correctly) after each iteration
calls dns_dbiterator_pause, and re-isc_task_sends itself.

That's an obvious bug, as we're holding a lock over an async task send -
if a task requesting write (e.g. prune_tree) is scheduled on the same
workers queue as update_quantum but before it, it will wait for the
write lock indefinitely, resulting in a deadlock.

To fix it we have to pause dbiterator in setup_update.
parent b22a5b6f
Pipeline #13074 canceled with stages
in 40 seconds
5201. [bug] Fix a possible deadlock in RPZ update code. [GL #973]
5200. [placeholder] 5200. [placeholder]
5199. [placeholder] 5199. [placeholder]
...@@ -1732,6 +1732,16 @@ setup_update(dns_rpz_zone_t *rpz) { ...@@ -1732,6 +1732,16 @@ setup_update(dns_rpz_zone_t *rpz) {
goto cleanup; goto cleanup;
} }
result = dns_dbiterator_pause(rpz->updbit);
if (result != ISC_R_SUCCESS) {
isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
"rpz: %s: failed to pause db iterator - %s",
domain, isc_result_totext(result));
goto cleanup;
cleanup: cleanup:
if (result != ISC_R_SUCCESS) { if (result != ISC_R_SUCCESS) {
if (rpz->updbit != NULL) if (rpz->updbit != NULL)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment