From 4a6509582320916b4d3e538dbdbabfba9f98acbb Mon Sep 17 00:00:00 2001 From: Matthijs Mekking Date: Fri, 13 Mar 2026 11:52:47 +0100 Subject: [PATCH] Only lock view->newzone.lock if not already locked Some code paths try to lock an already locked view->newzone.lock. For example, do_modzone() aqcuires the lock and then calls delete_zoneconf(), that wants to acquire the same lock. Add a parameter to delete_zoneconf() that informs the function if the lock has already been acquired. (cherry picked from commit 71587b0816a9458895aaa14a85539acd91afda38) --- bin/named/server.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/bin/named/server.c b/bin/named/server.c index 796b4cc97e..d2ac553ffc 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -13863,7 +13863,7 @@ cleanup: static isc_result_t delete_zoneconf(dns_view_t *view, cfg_parser_t *pctx, const cfg_obj_t *config, - const dns_name_t *zname, nzfwriter_t nzfwriter) { + const dns_name_t *zname, nzfwriter_t nzfwriter, bool locked) { isc_result_t result = ISC_R_NOTFOUND; const cfg_listelt_t *elt = NULL; const cfg_obj_t *zl = NULL; @@ -13876,7 +13876,9 @@ delete_zoneconf(dns_view_t *view, cfg_parser_t *pctx, const cfg_obj_t *config, REQUIRE(config != NULL); REQUIRE(zname != NULL); - LOCK(&view->new_zone_lock); + if (!locked) { + LOCK(&view->new_zone_lock); + } cfg_map_get(config, "zone", &zl); @@ -13917,7 +13919,9 @@ delete_zoneconf(dns_view_t *view, cfg_parser_t *pctx, const cfg_obj_t *config, } cleanup: - UNLOCK(&view->new_zone_lock); + if (!locked) { + UNLOCK(&view->new_zone_lock); + } return result; } @@ -13927,13 +13931,13 @@ do_addzone(named_server_t *server, ns_cfgctx_t *cfg, dns_view_t *view, bool redirect, isc_buffer_t **text) { isc_result_t result, tresult; dns_zone_t *zone = NULL; + bool locked = false; #ifndef HAVE_LMDB FILE *fp = NULL; bool cleanup_config = false; #else /* HAVE_LMDB */ MDB_txn *txn = NULL; MDB_dbi dbi; - bool locked = false; UNUSED(zoneconf); #endif @@ -14080,7 +14084,7 @@ cleanup: } if (result != ISC_R_SUCCESS && cleanup_config) { tresult = delete_zoneconf(view, cfg->add_parser, - cfg->nzf_config, name, NULL); + cfg->nzf_config, name, NULL, locked); RUNTIME_CHECK(tresult == ISC_R_SUCCESS); } #else /* HAVE_LMDB */ @@ -14106,13 +14110,13 @@ do_modzone(named_server_t *server, ns_cfgctx_t *cfg, dns_view_t *view, isc_result_t result, tresult; dns_zone_t *zone = NULL; bool added; + bool locked = false; #ifndef HAVE_LMDB FILE *fp = NULL; cfg_obj_t *z; #else /* HAVE_LMDB */ MDB_txn *txn = NULL; MDB_dbi dbi; - bool locked = false; #endif /* HAVE_LMDB */ /* Zone must already exist */ @@ -14202,7 +14206,7 @@ do_modzone(named_server_t *server, ns_cfgctx_t *cfg, dns_view_t *view, if (added) { result = delete_zoneconf(view, cfg->add_parser, cfg->nzf_config, dns_zone_getorigin(zone), - nzf_writeconf); + nzf_writeconf, locked); if (result != ISC_R_SUCCESS) { TCHECK(putstr(text, "former zone configuration " "not deleted: ")); @@ -14216,13 +14220,13 @@ do_modzone(named_server_t *server, ns_cfgctx_t *cfg, dns_view_t *view, if (cfg->vconfig == NULL) { result = delete_zoneconf( view, cfg->conf_parser, cfg->config, - dns_zone_getorigin(zone), NULL); + dns_zone_getorigin(zone), NULL, locked); } else { const cfg_obj_t *voptions = cfg_tuple_get(cfg->vconfig, "options"); result = delete_zoneconf( view, cfg->conf_parser, voptions, - dns_zone_getorigin(zone), NULL); + dns_zone_getorigin(zone), NULL, locked); } if (result != ISC_R_SUCCESS) { @@ -14504,7 +14508,7 @@ rmzone(void *arg) { #else /* ifdef HAVE_LMDB */ result = delete_zoneconf(view, cfg->add_parser, cfg->nzf_config, dns_zone_getorigin(zone), - nzf_writeconf); + nzf_writeconf, false); if (result != ISC_R_SUCCESS) { isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER, ISC_LOG_ERROR, @@ -14520,11 +14524,11 @@ rmzone(void *arg) { "options"); result = delete_zoneconf( view, cfg->conf_parser, voptions, - dns_zone_getorigin(zone), NULL); + dns_zone_getorigin(zone), NULL, false); } else { result = delete_zoneconf( view, cfg->conf_parser, cfg->config, - dns_zone_getorigin(zone), NULL); + dns_zone_getorigin(zone), NULL, false); } if (result != ISC_R_SUCCESS) { isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,