[PATCH] sigaction.2: Improve wording and add an example in the BUGS section

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

 



This patch clears up the wording of the first part of the BUGS section
of the sigaction.2 man page. Currently, it is very unclear when
exactly the bug can occur, and there is no example, which I aim to
fix. The text of the patch is partially based on the BUGS section of
the signal.2 man page.

I also attach a C program that, when run on an x86 Linux computer,
shows that my example behaves like I say it does. The code runs the
int instruction for each value from 0 to 255 with all registers set to
0 to show that all fields of the siginfo_t besides si_signo and
si_code equal zero. The program is based on the attachment to bug
205831 on the kernel bugtracker which first dealt with this issue,
which you can find here:
https://bugzilla.kernel.org/show_bug.cgi?id=205831. This is the code
of the test program:

#define CR "\n\t"
#define _GNU_SOURCE 1

#include <stdbool.h>
#include <signal.h>
#include <stdint.h>
#include <stdio.h>

static siginfo_t siginfo;

void handler(int sig, siginfo_t *info, void *ucontext) {
    ucontext_t *uc = (ucontext_t*) ucontext;
    const uint8_t *pc = (const uint8_t*) uc->uc_mcontext.gregs[REG_RIP];
    siginfo = *info;

    //skip the faulting instruction
    if(*pc == 0xCC || *pc == 0xF1)
        uc->uc_mcontext.gregs[REG_RIP] += 1;
    else if(*pc == 0xCD)
        uc->uc_mcontext.gregs[REG_RIP] += 2;
    else
        ; //assume the PC has already been advanced over the fault
}

static __attribute__((noinline)) void call_int(unsigned char argument) {
    asm volatile(
        "leaq 1f(%%rip), %%rcx"
        CR "addq   %%rcx, %%rax"
        CR "xor    %%rbx, %%rbx"
        CR "xor    %%rcx, %%rcx"
        CR "xor    %%rdx, %%rdx"
        CR "xor    %%rsi, %%rsi"
        CR "xor    %%rdi, %%rdi"
        CR "xor    %%rbp, %%rbp"
        CR "xor    %%r8, %%r8"
        CR "xor    %%r9, %%r8"
        CR "xor    %%r10, %%r10"
        CR "xor    %%r11, %%r11"
        CR "xor    %%r12, %%r12"
        CR "xor    %%r13, %%r13"
        CR "xor    %%r14, %%r14"
        CR "xor    %%r15, %%r15"
        CR "call   *%%rax"
        CR "jmp    2f"
        CR ".p2align 3"
        "\n1:"
        CR ".irp   i,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15"
        CR ".irp   j,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15"
        CR "xor    %%rax, %%rax"
        CR ".byte  0xCD,(\\i*16 + \\j)"
        CR "ret"
        CR ".p2align 3"
        CR ".endr"
        CR ".endr"
        "\n2:"

        :
        : "a" (argument * 8)
        : "rbx", "rcx", "rdx", "rsi", "rdi",
          "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
    );
}

int main() {
    struct sigaction sa = { 0 };
    sa.sa_sigaction = &handler;
    sa.sa_flags = SA_SIGINFO | SA_RESTART;
    sigaction(SIGSEGV, &sa, 0);
    sigaction(SIGTRAP, &sa, 0);

    for(int i = 0; i < 256; i++) {
        call_int(i);

        bool others_zeroed = (
            siginfo.si_errno == 0 &&
            siginfo.si_pid == 0 &&
            siginfo.si_uid == 0 &&
            siginfo.si_status == 0 &&
            siginfo.si_utime == 0 &&
            siginfo.si_stime == 0 &&
            siginfo.si_value.sival_ptr == 0 &&
            siginfo.si_value.sival_int == 0 &&
            siginfo.si_int == 0 &&
            siginfo.si_ptr == 0 &&
            siginfo.si_overrun == 0 &&
            siginfo.si_timerid == 0 &&
            siginfo.si_addr == 0 &&
            siginfo.si_band == 0 &&
            siginfo.si_fd == 0 &&
            siginfo.si_addr_lsb == 0 &&
            siginfo.si_lower == 0 &&
            siginfo.si_upper == 0 &&
            siginfo.si_pkey == 0 &&
            siginfo.si_call_addr == 0 &&
            siginfo.si_syscall == 0 &&
            siginfo.si_arch == 0
        );

        printf("int $0x%02x: sig=%2d code=%04x others_zeroed=%i\n",
            i,
            siginfo.si_signo,
            siginfo.si_code,
            others_zeroed
        );
    }

    return 0;
}

Signed-off-by: Mikołaj Kołek <kolek.mikolaj@xxxxxxxxx>
---
 man/man2/sigaction.2 | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/man/man2/sigaction.2 b/man/man2/sigaction.2
index df8826e71..dcd450ce9 100644
--- a/man/man2/sigaction.2
+++ b/man/man2/sigaction.2
@@ -1129,13 +1129,29 @@ .SS Undocumented
 See the relevant Linux kernel sources for details.
 This use is obsolete now.
 .SH BUGS
-When delivering a signal with a
+When delivering a signal resulting from a hardware exception with a
 .B SA_SIGINFO
 handler,
 the kernel does not always provide meaningful values
 for all of the fields of the
 .I siginfo_t
 that are relevant for that signal.
+For example, when the x86
+.I int
+instruction is called with a forbidden argument
+(any number other than 3 or 128), a
+.BR SIGSEGV
+signal is delivered, but the
+.I siginfo_t
+passed to the signal handler has all its fields besides
+.I si_signo
+and
+.I si_code
+set to zero, even if other fields should be set (as an example,
+.I si_addr
+should be non-zero for all
+.BR SIGSEGV
+signals).
 .P
 Up to and including Linux 2.6.13, specifying
 .B SA_NODEFER
-- 
2.46.0

>
> > when run on an x86
> > Linux computer, shows that my example behaves like I say it does. The
> > code runs the int instruction for each value from 0 to 255 with all
> > registers set to 0 to show what is contained in the siginfo_t returned
> > to the signal handler afterwards.
> >
> > The program is based on the attachment to bug 205831 on the kernel
> > Bugzilla, which first dealt with this issue, you can find that bug
> > report here: https://bugzilla.kernel.org/show_bug.cgi?id=205831. The
> > text of my contribution is also partially based on the BUGS section of
> > the signal.2 man page.
>
> Please CC the people that contributed in that discussion.
>
> Have a lovely night!
> Alex
>
>
> >
> > Signed-off-by: Mikołaj Kołek <kolek.mikolaj@xxxxxxxxx>
> > ---
> >  man/man2/sigaction.2 | 18 +++++++++++++++++-
> >  1 file changed, 17 insertions(+), 1 deletion(-)
> >
> > diff --git a/man/man2/sigaction.2 b/man/man2/sigaction.2
> > index df8826e71..2b797355b 100644
> > --- a/man/man2/sigaction.2
> > +++ b/man/man2/sigaction.2
> > @@ -1129,13 +1129,29 @@ .SS Undocumented
> >  See the relevant Linux kernel sources for details.
> >  This use is obsolete now.
> >  .SH BUGS
> > -When delivering a signal with a
> > +When delivering a signal resulting from a hardware exception with a
> >  .B SA_SIGINFO
> >  handler,
> >  the kernel does not always provide meaningful values
> >  for all of the fields of the
> >  .I siginfo_t
> >  that are relevant for that signal.
> > +For example, when the x86
> > +.I int
> > +instruction is called with a forbidden argument
> > +(any number other than 3 or 128), a
> > +.BR SIGSEGV
> > +signal is delivered, but the
> > +.I siginfo_t
> > +passed to the signal handler has all its fields besides
> > +.I si_signo
> > +and
> > +.I si_code
> > +set to zero, even if other fields should be set (as an example,
> > +.I si_addr
> > +should be non-zero for all
> > +.BR SIGSEGV
> > +signals).
> >  .P
> >  Up to and including Linux 2.6.13, specifying
> >  .B SA_NODEFER
> > --
> > 2.46.0
>
>
>
> --
> <https://www.alejandro-colomar.es/>





[Index of Archives]     [Kernel Documentation]     [Netdev]     [Linux Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux