bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: sigaction, SA_SIGINFO, and SIG_IGN


From: Bruno Haible
Subject: Re: sigaction, SA_SIGINFO, and SIG_IGN
Date: Wed, 18 Jun 2008 04:12:05 +0200
User-agent: KMail/1.5.4

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





reply via email to

[Prev in Thread] Current Thread [Next in Thread]