Messages in this thread | | | Date | Fri, 6 Jan 2023 21:53:56 +0100 | Subject | Re: [PATCH] proc: fix PIE proc-empty-vm, proc-pid-vm tests | From | Mirsad Goran Todorovac <> |
| |
Hi,
On 06. 01. 2023. 20:30, Alexey Dobriyan wrote: > vsyscall detection code uses direct call to the beginning of > the vsyscall page: > > asm ("call %P0" :: "i" (0xffffffffff600000)) > > It generates "call rel32" instruction but it is not relocated if binary > is PIE, so binary segfaults into random userspace address and vsyscall > page status is detected incorrectly. > > Do more direct: > > asm ("call *%rax") > > which doesn't do need any relocaltions. > > Mark g_vsyscall as volatile for a good measure, I didn't find instruction > setting it to 0. Now the code is obviously correct: > > xor eax, eax > mov rdi, rbp > mov rsi, rbp > mov DWORD PTR [rip+0x2d15], eax # g_vsyscall = 0 > mov rax, 0xffffffffff600000 > call rax > mov DWORD PTR [rip+0x2d02], 1 # g_vsyscall = 1 > mov eax, DWORD PTR ds:0xffffffffff600000 > mov DWORD PTR [rip+0x2cf1], 2 # g_vsyscall = 2 > mov edi, [rip+0x2ceb] # exit(g_vsyscall) > call exit > > Note: fixed proc-empty-vm test oopses 5.19.0-28-generic kernel > but this is separate story. > > Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com> > Reported-by: Mirsad Goran Todorovac <mirsad.todorovac@alu.unizg.hr> > --- > > tools/testing/selftests/proc/proc-empty-vm.c | 12 +++++++----- > tools/testing/selftests/proc/proc-pid-vm.c | 9 +++++---- > 2 files changed, 12 insertions(+), 9 deletions(-) > > --- a/tools/testing/selftests/proc/proc-empty-vm.c > +++ b/tools/testing/selftests/proc/proc-empty-vm.c > @@ -25,6 +25,7 @@ > #undef NDEBUG > #include <assert.h> > #include <errno.h> > +#include <stdint.h> > #include <stdio.h> > #include <stdlib.h> > #include <string.h> > @@ -41,7 +42,7 @@ > * 1: vsyscall VMA is --xp vsyscall=xonly > * 2: vsyscall VMA is r-xp vsyscall=emulate > */ > -static int g_vsyscall; > +static volatile int g_vsyscall; > static const char *g_proc_pid_maps_vsyscall; > static const char *g_proc_pid_smaps_vsyscall; > > @@ -147,11 +148,12 @@ static void vsyscall(void) > > g_vsyscall = 0; > /* gettimeofday(NULL, NULL); */ > + uint64_t rax = 0xffffffffff600000; > asm volatile ( > - "call %P0" > - : > - : "i" (0xffffffffff600000), "D" (NULL), "S" (NULL) nt> - : "rax", "rcx", "r11" > + "call *%[rax]" > + : [rax] "+a" (rax) > + : "D" (NULL), "S" (NULL) > + : "rcx", "r11" > ); > > g_vsyscall = 1; > --- a/tools/testing/selftests/proc/proc-pid-vm.c > +++ b/tools/testing/selftests/proc/proc-pid-vm.c > @@ -257,11 +257,12 @@ static void vsyscall(void) > > g_vsyscall = 0; > /* gettimeofday(NULL, NULL); */ > + uint64_t rax = 0xffffffffff600000; > asm volatile ( > - "call %P0" > - : > - : "i" (0xffffffffff600000), "D" (NULL), "S" (NULL) > - : "rax", "rcx", "r11" > + "call *%[rax]" > + : [rax] "+a" (rax) > + : "D" (NULL), "S" (NULL) > + : "rcx", "r11" > ); > > g_vsyscall = 1;
I can confirm that the patch fixed the core dump in the exact environment that used to reproduce the bug.
Apparently, it seems that gcc 12.2.0 -O2 optimiser on Ubuntu 22.10 kinetic kudu did some new creative stuff to Alexey's code. For someone interested, I have saved the assembly with and w/o -O2 ...
However, I have just found some spurious bug in proc-uptime-001.
But, this is another story ...
Thanks, Mirsad
-- Mirsad Goran Todorovac Sistem inženjer Grafički fakultet | Akademija likovnih umjetnosti Sveučilište u Zagrebu -- System engineer Faculty of Graphic Arts | Academy of Fine Arts University of Zagreb, Republic of Croatia The European Union
| |