From: Arran Cudbard-Bell Date: Wed, 8 Jun 2016 15:12:32 +0000 (-0400) Subject: Prevent signal loop X-Git-Tag: release_3_0_12~126 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=442b8f27d3ba8e460c871cb0abc593d39442e12d;p=thirdparty%2Ffreeradius-server.git Prevent signal loop Conflicts: src/include/libradius.h src/lib/misc.c --- diff --git a/src/include/libradius.h b/src/include/libradius.h index 545be09dfca..9626864e718 100644 --- a/src/include/libradius.h +++ b/src/include/libradius.h @@ -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); diff --git a/src/lib/debug.c b/src/lib/debug.c index 151b4f664ab..2a034a48a32 100644 --- a/src/lib/debug.c +++ b/src/lib/debug.c @@ -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 diff --git a/src/lib/misc.c b/src/lib/misc.c index 5ef00fe4dd1..8ed9e3a182b 100644 --- a/src/lib/misc.c +++ b/src/lib/misc.c @@ -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. */