From 4b222f154bc3d5d6755cf7089948bd4522ddb7af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= Date: Thu, 19 Jan 2023 09:14:53 +0100 Subject: [PATCH] Detach the zone views outside of the zone lock Detaching the views in the zone_shutdown() could lead to lock-order-inversion between adb->namelocks[bucket], adb->lock, view->lock and zone->lock. Detach the views outside of the section that zone-locked. Conflict: NA Reference: https://gitlab.isc.org/isc-projects/bind9/-/commit/4b222f154bc3d5d6755cf7089948bd4522ddb7af (cherry picked from commit 978a0ef84cfb08435c1b7664c6328521b743fb02) --- lib/dns/zone.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/lib/dns/zone.c b/lib/dns/zone.c index 9b025cdcaf..1763dbc306 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -14922,6 +14922,7 @@ zone_shutdown(isc_task_t *task, isc_event_t *event) { dns_zone_t *zone = (dns_zone_t *)event->ev_arg; bool free_needed, linked = false; dns_zone_t *raw = NULL, *secure = NULL; + dns_view_t *view = NULL, *prev_view = NULL; UNUSED(task); REQUIRE(DNS_ZONE_VALID(zone)); @@ -14968,13 +14969,15 @@ zone_shutdown(isc_task_t *task, isc_event_t *event) { LOCK_ZONE(zone); INSIST(zone != zone->raw); - /* Detach the views early, we don't need them anymore */ - if (zone->view != NULL) { - dns_view_weakdetach(&zone->view); - } - if (zone->prev_view != NULL) { - dns_view_weakdetach(&zone->prev_view); - } + /* + * Detach the views early, we don't need them anymore. However, we need + * to detach them outside of the zone lock to break the lock loop + * between view, adb and zone locks. + */ + view = zone->view; + zone->view = NULL; + prev_view = zone->prev_view; + zone->prev_view = NULL; if (linked) { isc_refcount_decrement(&zone->irefs); @@ -15036,6 +15039,14 @@ zone_shutdown(isc_task_t *task, isc_event_t *event) { zone->secure = NULL; } UNLOCK_ZONE(zone); + + if (view != NULL) { + dns_view_weakdetach(&view); + } + if (prev_view != NULL) { + dns_view_weakdetach(&prev_view); + } + if (raw != NULL) { dns_zone_detach(&raw); } -- 2.23.0