| From: Alexey Dobriyan <adobriyan@gmail.com> |
| Subject: proc: fix PIE proc-empty-vm, proc-pid-vm tests |
| Date: Fri, 6 Jan 2023 22:30:14 +0300 |
| |
| 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> |
| --- |
| |
| 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~proc-fix-pie-proc-empty-vm-proc-pid-vm-tests |
| +++ a/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) |
| - : "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~proc-fix-pie-proc-empty-vm-proc-pid-vm-tests |
| +++ a/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; |
| _ |