5316a017d0
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.
Link: https://lkml.kernel.org/r/Y7h2xvzKLg36DSq8@p183
Fixes:
|
||
---|---|---|
.. | ||
.gitignore | ||
config | ||
fd-001-lookup.c | ||
fd-002-posix-eq.c | ||
fd-003-kthread.c | ||
Makefile | ||
proc-empty-vm.c | ||
proc-fsconfig-hidepid.c | ||
proc-loadavg-001.c | ||
proc-multiple-procfs.c | ||
proc-pid-vm.c | ||
proc-self-map-files-001.c | ||
proc-self-map-files-002.c | ||
proc-self-syscall.c | ||
proc-self-wchan.c | ||
proc-subset-pid.c | ||
proc-tid0.c | ||
proc-uptime-001.c | ||
proc-uptime-002.c | ||
proc-uptime.h | ||
proc.h | ||
read.c | ||
self.c | ||
setns-dcache.c | ||
setns-sysvipc.c | ||
thread-self.c |