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@xxxxxxxxxx> >>> --- >>> These features are implemented in this patch series: >>> >> https://lore.kernel.org/linux-arm-kernel/cover.1605235762.git.pcc@xxxxxxxxxx/ >>> 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/