]> granicus.if.org Git - procps-ng/commitdiff
top: avoid a potential SEGV during program termination
authorJim Warner <james.warner@comcast.net>
Tue, 6 Aug 2019 05:00:00 +0000 (00:00 -0500)
committerCraig Small <csmall@dropbear.xyz>
Sat, 21 Sep 2019 21:32:03 +0000 (07:32 +1000)
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 <james.warner@comcast.net>
top/top.c

index 1db75fee16ae98ddf8eea38e680c438877bebca4..d75810f62f7d2f7b029f8a7453b71a6c93ca35c6 100644 (file)
--- 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