]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Bug 3574: crashes on reconfigure and startup
authorAmos Jeffries <squid3@treenet.co.nz>
Wed, 14 Oct 2015 05:29:29 +0000 (22:29 -0700)
committerAmos Jeffries <squid3@treenet.co.nz>
Wed, 14 Oct 2015 05:29:29 +0000 (22:29 -0700)
When Squid receives a reconfigure signal before its signal handler
has been registered on startup it will crash with unhandled signal
exceptions. This can be triggered on system boot when a resolv.conf
alteration signal wins a race with the daemon service initialization.

Fix:
 Register the reconfigure signal handler early and ignoring signals
 until initial squid.conf load has completed.

When Squid receives a reconfigure signal while it is already in the
process of reconfiguring, the two async sequences can interfere and
result in confusing fatal error or crashes.

Fix:
 Only allow one reconfigure sequence to be initiated at a time.

Also, if shutdown signal has been received while waiting for a
reconfigure to finish, let shutdown take precedence over any pending
reconfigure repeats.

 Based on work by Clint Byrum and D J Gardner, Ubuntu

src/main.cc

index d8885adc75fa30e87218d6596a358042f7988e94..ae749a0ed68cdfae1783d7453a003fef8918b68f 100644 (file)
@@ -224,8 +224,10 @@ SignalEngine::checkEvents(int timeout)
     PROF_start(SignalEngine_checkEvents);
 
     if (do_reconfigure) {
-        mainReconfigureStart();
-        do_reconfigure = 0;
+        if (!reconfiguring && configured_once) {
+            mainReconfigureStart();
+            do_reconfigure = 0;
+        } // else wait until previous reconfigure is done
     } else if (do_rotate) {
         mainRotate();
         do_rotate = 0;
@@ -889,6 +891,10 @@ mainReconfigureFinish(void *)
     writePidFile();     /* write PID file */
 
     reconfiguring = 0;
+
+    // ignore any pending re-reconfigure signals if shutdown received
+    if (do_shutdown)
+        do_reconfigure = 0;
 }
 
 static void
@@ -991,6 +997,7 @@ mainInitialize(void)
 
     squid_signal(SIGPIPE, SIG_IGN, SA_RESTART);
     squid_signal(SIGCHLD, sig_child, SA_NODEFER | SA_RESTART);
+    squid_signal(SIGHUP, reconfigure, SA_RESTART);
 
     setEffectiveUser();
 
@@ -1156,8 +1163,6 @@ mainInitialize(void)
 
 #endif
 
-    squid_signal(SIGHUP, reconfigure, SA_RESTART);
-
     squid_signal(SIGTERM, shut_down, SA_NODEFER | SA_RESETHAND | SA_RESTART);
 
     squid_signal(SIGINT, shut_down, SA_NODEFER | SA_RESETHAND | SA_RESTART);
@@ -1402,6 +1407,7 @@ SquidMain(int argc, char **argv)
         Format::Token::Init(); // XXX: temporary. Use a runners registry of pre-parse runners instead.
 
         try {
+            do_reconfigure = 0; // ignore any early (boot/startup) reconfigure signals
             parse_err = parseConfigFile(ConfigFile);
         } catch (...) {
             // for now any errors are a fatal condition...