From: Jim Warner Date: Tue, 6 Aug 2019 05:00:00 +0000 (-0500) Subject: top: avoid a potential SEGV during program termination X-Git-Tag: v4.0.0~417 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=90c22e64ffc52e01ea2c9b81680d4b4a37f2d8c4;p=procps-ng top: avoid a potential SEGV during program termination The backtrace shown in the bug report referenced below illustrates a 'normal' program termination interrupted with some signal, ultimately then causing a top crash. So this commit just rearranges a little code such that all signals will be blocked during that rather lengthy end of program processing regardless of how initiated. [ in that report, ignore the assertion regarding the ] [ '-n' option. it obviously was not '1' since do_key ] [ had been called, which otherwise wouldn't be true. ] [ and when it is '1' the -d option would be ignored. ] Reference(s): https://bugzilla.redhat.com/show_bug.cgi?id=1737552 Signed-off-by: Jim Warner --- diff --git a/top/top.c b/top/top.c index 1db75fee..d75810f6 100644 --- a/top/top.c +++ b/top/top.c @@ -332,6 +332,11 @@ static void at_eoj (void) { * The real program end */ static void bye_bye (const char *str) __attribute__((__noreturn__)); static void bye_bye (const char *str) { + sigset_t ss; + +// POSIX.1-2004 async-signal-safe: sigfillset, sigprocmask + sigfillset(&ss); + sigprocmask(SIG_BLOCK, &ss, NULL); at_eoj(); // restore tty in preparation for exit #ifdef ATEOJ_RPTSTD { @@ -446,12 +451,6 @@ static void sig_abexit (int sig) { * SIGUSR1 and SIGUSR2 */ static void sig_endpgm (int dont_care_sig) __attribute__((__noreturn__)); static void sig_endpgm (int dont_care_sig) { - sigset_t ss; - -// POSIX.1-2004 async-signal-safe: sigfillset, sigprocmask - sigfillset(&ss); - sigprocmask(SIG_BLOCK, &ss, NULL); - Frames_signal = BREAK_sig; bye_bye(NULL); (void)dont_care_sig; } // end: sig_endpgm