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: 5bc73bb345 ("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>
This commit is contained in:
Alexey Dobriyan 2023-01-06 22:30:14 +03:00 committed by Andrew Morton
parent 8651a137e6
commit 5316a017d0
2 changed files with 12 additions and 9 deletions

View File

@ -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;

View File

@ -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;