Hi Mikołaj, On Wed, Aug 07, 2024 at 03:58:32PM GMT, Mikołaj Kołek wrote: > Hi Alejandro, > > On Wed, Aug 7, 2024 at 12:20 AM Alejandro Colomar <alx@xxxxxxxxxx> wrote: > > > > Hi Mikołaj, > > > > On Wed, Aug 07, 2024 at 12:07:57AM GMT, Mikołaj Kołek wrote: > > > 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. > > > > > > I also attach the source code of a C program that, > > > > Please include the example program in the commit message. > > I have updated the patch to include the code in the commit message. I > have also reorganised the code a bit, to be simpler and for the output > to be easier to understand. Here is the updated patch, I hope it will > be to your satisfaction: Yup; thanks! > > From 6f80374c12ad5e4917e8af8d0814201b4a916a49 Mon Sep 17 00:00:00 2001 > From: Mikołaj Kołek <kolek.mikolaj@xxxxxxxxx> > Date: Wed, 7 Aug 2024 13:14:21 +0200 > Subject: [PATCH] sigaction.2: Improve wording and add an example in the BUGS > section > MIME-Version: 1.0 > Content-Type: text/plain; charset=UTF-8 > Content-Transfer-Encoding: 8bit > > 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> Patch applied. Have a lovely day! Alex > --- > 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/> > -- <https://www.alejandro-colomar.es/>
Attachment:
signature.asc
Description: PGP signature