Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

proc: fix PIE proc-empty-vm, proc-pid-vm tests

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: 5bc73bb3451b9 ("proc: test how it holds up with mapping'less process")
Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
Reported-by: Mirsad Goran Todorovac <mirsad.todorovac@alu.unizg.hr>
Tested-by: Mirsad Goran Todorovac <mirsad.todorovac@alu.unizg.hr>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Alexey Dobriyan and committed by
Andrew Morton
5316a017 8651a137

+12 -9
+7 -5
tools/testing/selftests/proc/proc-empty-vm.c
··· 25 25 #undef NDEBUG 26 26 #include <assert.h> 27 27 #include <errno.h> 28 + #include <stdint.h> 28 29 #include <stdio.h> 29 30 #include <stdlib.h> 30 31 #include <string.h> ··· 42 41 * 1: vsyscall VMA is --xp vsyscall=xonly 43 42 * 2: vsyscall VMA is r-xp vsyscall=emulate 44 43 */ 45 - static int g_vsyscall; 44 + static volatile int g_vsyscall; 46 45 static const char *g_proc_pid_maps_vsyscall; 47 46 static const char *g_proc_pid_smaps_vsyscall; 48 47 ··· 148 147 149 148 g_vsyscall = 0; 150 149 /* gettimeofday(NULL, NULL); */ 150 + uint64_t rax = 0xffffffffff600000; 151 151 asm volatile ( 152 - "call %P0" 153 - : 154 - : "i" (0xffffffffff600000), "D" (NULL), "S" (NULL) 155 - : "rax", "rcx", "r11" 152 + "call *%[rax]" 153 + : [rax] "+a" (rax) 154 + : "D" (NULL), "S" (NULL) 155 + : "rcx", "r11" 156 156 ); 157 157 158 158 g_vsyscall = 1;
+5 -4
tools/testing/selftests/proc/proc-pid-vm.c
··· 257 257 258 258 g_vsyscall = 0; 259 259 /* gettimeofday(NULL, NULL); */ 260 + uint64_t rax = 0xffffffffff600000; 260 261 asm volatile ( 261 - "call %P0" 262 - : 263 - : "i" (0xffffffffff600000), "D" (NULL), "S" (NULL) 264 - : "rax", "rcx", "r11" 262 + "call *%[rax]" 263 + : [rax] "+a" (rax) 264 + : "D" (NULL), "S" (NULL) 265 + : "rcx", "r11" 265 266 ); 266 267 267 268 g_vsyscall = 1;