]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Rescan interfaces before dropping privileges
authorOndřej Surý <ondrej@isc.org>
Thu, 6 Oct 2022 16:00:06 +0000 (18:00 +0200)
committerOndřej Surý <ondrej@isc.org>
Tue, 1 Nov 2022 10:48:56 +0000 (11:48 +0100)
The ns_interfacemgr_scan() now requires the loopmgr to be running, so we
need to end exclusive mode for the rescan and then begin it again.

This is relatively safe operation (because the scan happens on the timer
anyway), but we need to ensure that we won't load the configuration from
different threads.  This is already the case because the initial load
happens on the main thread and the control channel also listens just on
the main loop.

bin/named/server.c

index 4568fdd1e1c82921aa55f80fe0dc793dea9c9647..b95d1ee108ba026c42090217d8a85cd0eb5a2a87 100644 (file)
@@ -7071,7 +7071,7 @@ static void
 interface_timer_tick(void *arg) {
        named_server_t *server = (named_server_t *)arg;
 
-       ns_interfacemgr_scan(server->interfacemgr, false, false);
+       (void)ns_interfacemgr_scan(server->interfacemgr, false, false);
 }
 
 static void
@@ -8403,6 +8403,11 @@ load_configuration(const char *filename, named_server_t *server,
        dns_aclenv_t *env =
                ns_interfacemgr_getaclenv(named_g_server->interfacemgr);
 
+       /*
+        * Require the reconfiguration to happen always on the main loop
+        */
+       REQUIRE(isc_loop_current(named_g_loopmgr) == named_g_mainloop);
+
        ISC_LIST_INIT(kasplist);
        ISC_LIST_INIT(viewlist);
        ISC_LIST_INIT(builtin_viewlist);
@@ -9038,6 +9043,32 @@ load_configuration(const char *filename, named_server_t *server,
                }
        }
 
+       if (first_time) {
+               isc_task_endexclusive(server->task);
+
+               /*
+                * Rescan the interface list to pick up changes in the
+                * listen-on option.
+                */
+               result = ns_interfacemgr_scan(server->interfacemgr, true, true);
+
+               isc_task_beginexclusive(server->task);
+
+               /*
+                * Check that named is able to TCP listen on at least one
+                * interface. Otherwise, another named process could be running
+                * and we should fail.
+                */
+               if (result == ISC_R_ADDRINUSE) {
+                       isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
+                                     NAMED_LOGMODULE_SERVER, ISC_LOG_ERROR,
+                                     "unable to listen on any configured "
+                                     "interfaces");
+                       result = ISC_R_FAILURE;
+                       goto cleanup_v6portset;
+               }
+       }
+
        /*
         * Arrange for further interface scanning to occur periodically
         * as specified by the "interface-interval" option.
@@ -9767,26 +9798,7 @@ load_configuration(const char *filename, named_server_t *server,
                goto cleanup_altsecrets;
        }
 
-       /*
-        * Rescan the interface list to pick up changes in the
-        * listen-on option.  It's important that we do this before we try
-        * to configure the query source, since the dispatcher we use might
-        * be shared with an interface.
-        */
-       result = ns_interfacemgr_scan(server->interfacemgr, true, true);
-
-       /*
-        * Check that named is able to TCP listen on at least one
-        * interface. Otherwise, another named process could be running
-        * and we should fail.
-        */
-       if (first_time && (result == ISC_R_ADDRINUSE)) {
-               isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
-                             NAMED_LOGMODULE_SERVER, ISC_LOG_ERROR,
-                             "unable to listen on any configured interfaces");
-               result = ISC_R_FAILURE;
-               goto cleanup_altsecrets;
-       }
+       (void)ns_interfacemgr_scan(server->interfacemgr, true, true);
 
        /*
         * These cleans up either the old production view list