Re: [PATCH] proc: fix PIE proc-empty-vm, proc-pid-vm tests

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxx>
Reported-by: Mirsad Goran Todorovac <mirsad.todorovac@xxxxxxxxxxxx>
---

  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




[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [NTFS 3]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [NTFS 3]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux