]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Bug 3574: crashes on reconfigure and startup
authorAmos Jeffries <squid3@treenet.co.nz>
Mon, 12 Oct 2015 01:38:02 +0000 (18:38 -0700)
committerAmos Jeffries <squid3@treenet.co.nz>
Mon, 12 Oct 2015 01:38:02 +0000 (18:38 -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.

 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.
 Only allowing 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 6cb50cb9912fdd5377b72838fe0aa195f267c9d2..6ec0437c04e3a01d37d23c07b558a0ef4100f43c 100644 (file)
@@ -238,8 +238,10 @@ SignalEngine::checkEvents(int)
     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;
@@ -960,6 +962,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
@@ -1062,6 +1068,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();
 
@@ -1227,8 +1234,6 @@ mainInitialize(void)
 
 #endif
 
-    squid_signal(SIGHUP, reconfigure, SA_RESTART);
-
     squid_signal(SIGTERM, shut_down, SA_RESTART);
 
     squid_signal(SIGINT, shut_down, SA_RESTART);
@@ -1471,6 +1476,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...