Eric Blake wrote: > |> struct sigaction action; > |> > |> if (sigaction (fatal_signals[i], NULL, &action) >= 0 > |> + && (action.sa_flags & SA_SIGINFO) == 0 > |> && action.sa_handler == SIG_IGN) > |> fatal_signals[i] = -1; > |> } > > Pre-existing bug. POSIX states that sa_handler and sa_siginfo may, but > not must, occupy overlapping space, and that sa_handler must not be > accessed if sa_flags includes SA_SIGINFO. Therefore, it is conceivable to > have an implementation where action.sa_handler is garbage and happens to > be SIG_IGN, because only action.sa_siginfo was valid to access. (In > reality, all implementations I am aware of, including my replacement, use > a union and let the two function definitions overlap, so this is more of a > theoretical bug ...
Sometimes you can also kill working programs by attempting too much standards compliance: What if someone actually installs a handler with SA_SIGINFO and SIG_IGN? The kernel will not deliver such signals. I.e. the right way to fix the code would be if (sigaction (fatal_signals[i], NULL, &action) >= 0 && (action.sa_flags & SA_SIGINFO ? (void *) action.sa_sigaction == (void *) SIG_IGN : action.sa_handler == SIG_IGN)) [Note that you cannot cast a function pointer into a different function pointer. gcc generates code equivalent to an abort() sometimes if you do that.] > sa_handler must not be accessed if sa_flags includes SA_SIGINFO. The wording is not as clear as you might think. POSIX is not correct about the type of SIG_DFL and SIG_IGN: In <http://www.opengroup.org/susv3/basedefs/signal.h.html> it says "... constants, each of which expands to a distinct constant expression of the type void (*)(int) ...: SIG_DFL SIG_IGN" but also "void (*)(int, siginfo_t *, void *) sa_sigaction Pointer to signal handler function or one of the macros SIG_IGN or SIG_DFL." But sa_sigaction cannot be SIG_IGN or SIG_DFL because they are of different types! Also in <file:/other/www/www.opengroup.org/susv3/functions/sigaction.html> the sentence "If the SA_SIGINFO flag is set in the sa_flags field, and the implementation supports the Realtime Signals Extension option or the XSI Extension option, the sa_sigaction field specifies a signal-catching function." indicates that the sa_sigaction field can never be SIG_DFL or SIG_IGN. Hence you always need to test sa_handler for that. According to this reading of POSIX, one is not allowed to use SA_SIGINFO with SIG_DFL or SIG_IGN; in this case, the existing code in lib/fatal-signal.c is plain correct. In summary, this is too much theoretical head-ache for something which works in practice - since sa_handler and sa_sigaction share the same memory location. You can put in a comment if you like. But no need to change code that works everywhere. Bruno