[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <cd0cbfc0-cf8a-c97a-d03f-016c8f9b9fa3@alu.unizg.hr>
Date: Fri, 6 Jan 2023 21:53:56 +0100
From: Mirsad Goran Todorovac <mirsad.todorovac@....unizg.hr>
To: Alexey Dobriyan <adobriyan@...il.com>,
Andrew Morton <akpm@...ux-foundation.org>
Cc: linux-kselftest@...r.kernel.org, Shuah Khan <shuah@...nel.org>,
Brian Foster <bfoster@...hat.com>,
Guo Zhengkui <guozhengkui@...o.com>,
linux-fsdevel@...r.kernel.org, linux-kernel@...r.kernel.org,
Thorsten Leemhuis <regressions@...mhuis.info>
Subject: Re: [PATCH] proc: fix PIE proc-empty-vm, proc-pid-vm tests
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@...il.com>
> Reported-by: Mirsad Goran Todorovac <mirsad.todorovac@....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
Powered by blists - more mailing lists