[PATCH v2] sigaction.2: Document SA_EXPOSE_TAGBITS and the flag support detection protocol

Peter Collingbourne pcc at google.com
Mon Dec 21 13:17:26 EST 2020


Hi Alex,

The feature is due to be merged in 5.11 so presumably we should wait
until then. I have no updates for the patch; at this point I am hoping
for comments (or a Reviewed-by) from Dave.

I saw your s/.IR/.I/ and I will do that once I have another update for
the patch.

Peter

On Fri, Dec 18, 2020 at 2:27 AM Alejandro Colomar (man-pages)
<alx.manpages at gmail.com> wrote:
>
> Hi Peter,
>
> Linux 5.10 has been recently released.
> Was this merged to 5.10 or 5.11?
> Do you have any updates for this patch?
>
> Thanks,
>
> Alex
>
> On 11/18/20 3:04 PM, Alejandro Colomar (man-pages) wrote:
> >
> >
> > On 11/18/20 12:42 PM, Alejandro Colomar (man-pages) wrote:
> >> [[ Removed some CCs because gmail
> >>    didn't allow me to send it with so many CCs:
> >>    Kevin B., Andrey K., Helge D., David S.
> >> ]]
> >>
> >> On 11/18/20 12:54 AM, Peter Collingbourne wrote:
> >>> Signed-off-by: Peter Collingbourne <pcc at google.com>
> >>> ---
> >>> These features are implemented in this patch series:
> >>>
> >> https://lore.kernel.org/linux-arm-kernel/cover.1605235762.git.pcc@google.com/
> >>> which is still under review, so the patch should not be applied
> >>> yet.
> >>>
> >>> Alejandro, thanks for the review. Since the patch was almost
> >>> rewritten I didn't base this on your patch, instead I tried to
> >>> use the correct formatting in this patch.
> >>
> >> Hi Peter,
> >>
> >> Fine.
> >> See below a small fix.
> >
> > D'oh!
> > Fixing the CCs I forgot to add the fix to the code.
> > See below now.
> >
> >>
> >> Cheers,
> >>
> >> Alex
> >>
> >>>
> >>> v2:
> >>> - fix formatting
> >>> - address feedback from Dave
> >>>
> >>>  man2/sigaction.2 | 125 +++++++++++++++++++++++++++++++++++++++++++++++
> >>>  1 file changed, 125 insertions(+)
> >>>
> >>> diff --git a/man2/sigaction.2 b/man2/sigaction.2
> >>> index 6a8142324..0e4236a43 100644
> >>> --- a/man2/sigaction.2
> >>> +++ b/man2/sigaction.2
> >>> @@ -250,6 +250,44 @@ This flag is meaningful only when establishing a
> >> signal handler.
> >>>  .\" .I sa_sigaction
> >>>  .\" field was added in Linux 2.1.86.)
> >>>  .\"
> >>> +.TP
> >>> +.BR 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
> >>> +.IR oldact->sa_flags
> >
> > s/.IR/.I/
> >
> > There's no roman part there.
> >
> >>> +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.x)"
> >>> +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.x
> >>> +must use
> >>> +.B SA_UNSUPPORTED
> >>> +to probe for support.
> >>>  .SS The siginfo_t argument to a SA_SIGINFO handler
> >>>  When the
> >>>  .B SA_SIGINFO
> >>> @@ -833,6 +871,93 @@ Triggered by a
> >>>  .BR seccomp (2)
> >>>  filter rule.
> >>>  .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.x 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.x.
> >>> +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 = {};
> >>> +  act.sa_flags = SA_SIGINFO | SA_UNSUPPORTED | SA_EXPOSE_TAGBITS;
> >>> +  act.sa_sigaction = handler;
> >>> +  if (sigaction(SIGSEGV, &act, 0) != 0) {
> >>> +    perror("sigaction");
> >>> +    return 1;
> >>> +  }
> >>> +
> >>> +  /* Force a SIGSEGV. */
> >>> +  *(volatile int *)0 = 0;
> >>> +  return 1;
> >>> +}
> >>> +.EE
> >>>  .SH RETURN VALUE
> >>>  .BR sigaction ()
> >>>  returns 0 on success; on error, \-1 is returned, and
> >>>
>
> --
> Alejandro Colomar
> Linux man-pages comaintainer; https://www.kernel.org/doc/man-pages/
> http://www.alejandro-colomar.es/



More information about the linux-arm-kernel mailing list