mirror of https://github.com/mkerrisk/man-pages
sigaction.2: Document SA_EXPOSE_TAGBITS and the flag support detection protocol
Signed-off-by: Peter Collingbourne <pcc@google.com> Signed-off-by: Alejandro Colomar <alx.manpages@gmail.com> Signed-off-by: Michael Kerrisk <mtk.manpages@gmail.com>
This commit is contained in:
parent
9b6cce9936
commit
7dd4af5158
123
man2/sigaction.2
123
man2/sigaction.2
|
@ -261,6 +261,44 @@ This flag is meaningful only when establishing a signal handler.
|
||||||
.\" .I sa_sigaction
|
.\" .I sa_sigaction
|
||||||
.\" field was added in Linux 2.1.86.)
|
.\" field was added in Linux 2.1.86.)
|
||||||
.\"
|
.\"
|
||||||
|
.TP
|
||||||
|
.B SA_UNSUPPORTED
|
||||||
|
Used to dynamically probe for flag bit support.
|
||||||
|
.IP
|
||||||
|
If an attempt to register a handler succeeds with this flag set in
|
||||||
|
.I act->sa_flags
|
||||||
|
alongside other flags that are potentially unsupported by the kernel,
|
||||||
|
and an immediately subsequent
|
||||||
|
.BR sigaction ()
|
||||||
|
call specifying the same signal number n and with non-NULL
|
||||||
|
.I oldact
|
||||||
|
yields
|
||||||
|
.B SA_UNSUPPORTED
|
||||||
|
.I clear
|
||||||
|
in
|
||||||
|
.IR oldact->sa_flags ,
|
||||||
|
then
|
||||||
|
.I oldact->sa_flags
|
||||||
|
may be used as a bitmask
|
||||||
|
describing which of the potentially unsupported flags are,
|
||||||
|
in fact, supported.
|
||||||
|
See the section "Dynamically probing for flag bit support"
|
||||||
|
below for more details.
|
||||||
|
.TP
|
||||||
|
.BR SA_EXPOSE_TAGBITS " (since Linux 5.11)"
|
||||||
|
Normally, when delivering a signal,
|
||||||
|
an architecture-specific set of tag bits are cleared from the
|
||||||
|
.I si_addr
|
||||||
|
field of
|
||||||
|
.IR siginfo_t .
|
||||||
|
If this flag is set,
|
||||||
|
an architecture-specific subset of the tag bits will be preserved in
|
||||||
|
.IR si_addr .
|
||||||
|
.IP
|
||||||
|
Programs that need to be compatible with Linux versions older than 5.11
|
||||||
|
must use
|
||||||
|
.B SA_UNSUPPORTED
|
||||||
|
to probe for support.
|
||||||
.SS The siginfo_t argument to a SA_SIGINFO handler
|
.SS The siginfo_t argument to a SA_SIGINFO handler
|
||||||
When the
|
When the
|
||||||
.B SA_SIGINFO
|
.B SA_SIGINFO
|
||||||
|
@ -846,6 +884,91 @@ Triggered by a
|
||||||
.BR seccomp (2)
|
.BR seccomp (2)
|
||||||
filter rule.
|
filter rule.
|
||||||
.RE
|
.RE
|
||||||
|
.SS Dynamically probing for flag bit support
|
||||||
|
The
|
||||||
|
.BR sigaction ()
|
||||||
|
call on Linux accepts unknown bits set in
|
||||||
|
.I act->sa_flags
|
||||||
|
without error.
|
||||||
|
The behavior of the kernel starting with Linux 5.11 is that a second
|
||||||
|
.BR sigaction ()
|
||||||
|
will clear unknown bits from
|
||||||
|
.IR oldact->sa_flags .
|
||||||
|
However, historically, a second
|
||||||
|
.BR sigaction ()
|
||||||
|
call would typically leave those bits set in
|
||||||
|
.IR oldact->sa_flags .
|
||||||
|
.PP
|
||||||
|
This means that support for new flags cannot be detected
|
||||||
|
simply by testing for a flag in
|
||||||
|
.IR sa_flags ,
|
||||||
|
and a program must test that
|
||||||
|
.B SA_UNSUPPORTED
|
||||||
|
has been cleared before relying on the contents of
|
||||||
|
.IR sa_flags .
|
||||||
|
.PP
|
||||||
|
Since the behavior of the signal handler cannot be guaranteed
|
||||||
|
unless the check passes,
|
||||||
|
it is wise to either block the affected signal
|
||||||
|
while registering the handler and performing the check in this case,
|
||||||
|
or where this is not possible,
|
||||||
|
for example if the signal is synchronous, to issue the second
|
||||||
|
.BR sigaction ()
|
||||||
|
in the signal handler itself.
|
||||||
|
.PP
|
||||||
|
In kernels that do not support a specific flag,
|
||||||
|
the kernel's behavior is as if the flag was not set,
|
||||||
|
even if the flag was set in
|
||||||
|
.IR act->sa_flags .
|
||||||
|
.PP
|
||||||
|
The flags
|
||||||
|
.BR SA_NOCLDSTOP ,
|
||||||
|
.BR SA_NOCLDWAIT ,
|
||||||
|
.BR SA_SIGINFO ,
|
||||||
|
.BR SA_ONSTACK ,
|
||||||
|
.BR SA_RESTART ,
|
||||||
|
.BR SA_NODEFER ,
|
||||||
|
.BR SA_RESETHAND ,
|
||||||
|
and, if defined by the architecture,
|
||||||
|
.B SA_RESTORER
|
||||||
|
may not be reliably probed for using this mechanism,
|
||||||
|
because they were introduced before Linux 5.11.
|
||||||
|
However, in general, programs may assume that these flags are supported,
|
||||||
|
since they have all been supported since Linux 2.6,
|
||||||
|
which was released in the year 2003.
|
||||||
|
.PP
|
||||||
|
The following example program exits with status 0 if
|
||||||
|
.B SA_EXPOSE_TAGBITS
|
||||||
|
is determined to be supported, and 1 otherwise.
|
||||||
|
.PP
|
||||||
|
.EX
|
||||||
|
#include <signal.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
void handler(int signo, siginfo_t *info, void *context) {
|
||||||
|
struct sigaction oldact;
|
||||||
|
if (sigaction(SIGSEGV, 0, &oldact) == 0 &&
|
||||||
|
!(oldact.sa_flags & SA_UNSUPPORTED) &&
|
||||||
|
(oldact.sa_flags & SA_EXPOSE_TAGBITS)) {
|
||||||
|
_exit(0);
|
||||||
|
} else {
|
||||||
|
_exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
struct sigaction act = {0};
|
||||||
|
act.sa_flags = SA_SIGINFO | SA_UNSUPPORTED | SA_EXPOSE_TAGBITS;
|
||||||
|
act.sa_sigaction = handler;
|
||||||
|
if (sigaction(SIGSEGV, &act, 0) != 0) {
|
||||||
|
perror("sigaction");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
raise(SIGSEGV);
|
||||||
|
}
|
||||||
|
.EE
|
||||||
.SH RETURN VALUE
|
.SH RETURN VALUE
|
||||||
.BR sigaction ()
|
.BR sigaction ()
|
||||||
returns 0 on success; on error, \-1 is returned, and
|
returns 0 on success; on error, \-1 is returned, and
|
||||||
|
|
Loading…
Reference in New Issue