]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Prevent signal loop
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Wed, 8 Jun 2016 15:12:32 +0000 (11:12 -0400)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Wed, 8 Jun 2016 15:26:18 +0000 (11:26 -0400)
Conflicts:
src/include/libradius.h
src/lib/misc.c

src/include/libradius.h
src/lib/debug.c
src/lib/misc.c

index 545be09dfca447007423245068397e1aca51a6f9..9626864e718afeff9e7d3c5271f771d45f3a3062 100644 (file)
@@ -703,6 +703,7 @@ void                fr_printf_log(char const *, ...) CC_HINT(format (printf, 1, 2));
  *     Several handy miscellaneous functions.
  */
 int            fr_set_signal(int sig, sig_t func);
+int            fr_unset_signal(int sig);
 int            fr_link_talloc_ctx_free(TALLOC_CTX *parent, TALLOC_CTX *child);
 char const     *fr_inet_ntop(int af, void const *src);
 char const     *ip_ntoa(char *, uint32_t);
index 151b4f664ab1ec96378db0f6d6b18bd6b8f4eea6..2a034a48a321a5ab163ef7cd802f6a56a3fc8ea5 100644 (file)
@@ -703,11 +703,11 @@ NEVER_RETURNS void fr_fault(int sig)
        if (strlen(p) >= left) goto oob;
        strlcpy(out, p, left);
 
-       FR_FAULT_LOG("Calling: %s", cmd);
-
        {
                bool disable = false;
 
+               FR_FAULT_LOG("Calling: %s", cmd);
+
                /*
                 *      Here we temporarily enable the dumpable flag so if GBD or LLDB
                 *      is called in the panic_action, they can pattach to the running
@@ -738,13 +738,23 @@ NEVER_RETURNS void fr_fault(int sig)
                        }
                }
 
-               fr_exit_now(1);
+               FR_FAULT_LOG("Panic action exited with %i", code);
+
+               fr_exit_now(code);
        }
 
-       FR_FAULT_LOG("Panic action exited with %i", code);
 
 finish:
+       /*
+        *      (Re-)Raise the signal, so that if we're running under
+        *      a debugger, the debugger can break when it receives
+        *      the signal.
+        */
+       fr_unset_signal(sig);   /* Make sure we don't get into a loop */
+
        raise(sig);
+
+       fr_exit_now(1);         /* Function marked as noreturn */
 }
 
 /** Callback executed on fatal talloc error
index 5ef00fe4dd1ed7273bf9fbc1454842b53a382ce2..8ed9e3a182b412eb496da9b179b2d0d7d46ffd44 100644 (file)
@@ -80,6 +80,28 @@ int fr_set_signal(int sig, sig_t func)
        return 0;
 }
 
+/** Uninstall a signal for a specific handler
+ *
+ * man sigaction says these are fine to call from a signal handler.
+ *
+ * @param sig SIGNAL
+ */
+int fr_unset_signal(int sig)
+{
+#ifdef HAVE_SIGACTION
+        struct sigaction act;
+
+        memset(&act, 0, sizeof(act));
+        act.sa_flags = 0;
+        sigemptyset(&act.sa_mask);
+        act.sa_handler = SIG_DFL;
+
+        return sigaction(sig, &act, NULL);
+#else
+        return signal(sig, SIG_DFLT);
+#endif
+}
+
 static int _fr_trigger_talloc_ctx_free(fr_talloc_link_t *trigger)
 {
        if (trigger->armed) talloc_free(trigger->child);
@@ -322,7 +344,7 @@ int fr_pton4(fr_ipaddr_t *out, char const *value, ssize_t inlen, bool resolve, b
 
                return 0;
        }
-       
+
        /*
         *      Copy the IP portion into a temporary buffer if we haven't already.
         */