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(-)
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@gmail.com>
Reported-by: Mirsad Goran Todorovac <mirsad.todorovac@alu.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)
- : "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;
Hi all, In the same environment as the previous bug report (Lenovo Ideapad 3 15ITL6 laptop running Ubuntu 22.10 kinetic kudu and 6.2-rc2 vanilla Torvalds tree kernel), the next test in the ...selftest/proc/* sequence spuriously fails in assert (i1 <= i0). Please note that the compiler is the novelty GCC 12.2.0-3ubuntu1. This was previously hidden by premature hang in the `make kselftest` run due to proc-empty-vm an proc-pid-vm problems that are now fixed. root@marvin-IdeaPad-3-15ITL6:/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc# ./proc-uptime-001 root@marvin-IdeaPad-3-15ITL6:/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc# ./proc-uptime-001 root@marvin-IdeaPad-3-15ITL6:/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc# ./proc-uptime-001 proc-uptime-001: proc-uptime-001.c:39: main: Assertion `i1 >= i0' failed. Aborted (core dumped) root@marvin-IdeaPad-3-15ITL6:/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc# ./proc-uptime-001 proc-uptime-001: proc-uptime-001.c:39: main: Assertion `i1 >= i0' failed. Aborted (core dumped) root@marvin-IdeaPad-3-15ITL6:/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc# ./proc-uptime-001 root@marvin-IdeaPad-3-15ITL6:/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc# ./proc-uptime-001 root@marvin-IdeaPad-3-15ITL6:/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc# ./proc-uptime-001 root@marvin-IdeaPad-3-15ITL6:/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc# ./proc-uptime-001 root@marvin-IdeaPad-3-15ITL6:/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc# ./proc-uptime-001 proc-uptime-001: proc-uptime-001.c:39: main: Assertion `i1 >= i0' failed. Aborted (core dumped) root@marvin-IdeaPad-3-15ITL6:/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc# ./proc-uptime-001 root@marvin-IdeaPad-3-15ITL6:/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc# ./proc-uptime-001 proc-uptime-001: proc-uptime-001.c:39: main: Assertion `i1 >= i0' failed. Aborted (core dumped) root@marvin-IdeaPad-3-15ITL6:/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc# ./proc-uptime-001 root@marvin-IdeaPad-3-15ITL6:/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc# ./proc-uptime-001 proc-uptime-001: proc-uptime-001.c:39: main: Assertion `i1 >= i0' failed. Aborted (core dumped) root@marvin-IdeaPad-3-15ITL6:/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc# ./proc-uptime-001 root@marvin-IdeaPad-3-15ITL6:/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc# ./proc-uptime-001 root@marvin-IdeaPad-3-15ITL6:/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc# ./proc-uptime-001 proc-uptime-001: proc-uptime-001.c:39: main: Assertion `i1 >= i0' failed. Aborted (core dumped) root@marvin-IdeaPad-3-15ITL6:/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc# ./proc-uptime-001 proc-uptime-001: proc-uptime-001.c:39: main: Assertion `i1 >= i0' failed. Aborted (core dumped) root@marvin-IdeaPad-3-15ITL6:/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc# ./proc-uptime-001 proc-uptime-001: proc-uptime-001.c:39: main: Assertion `i1 >= i0' failed. Aborted (core dumped) root@marvin-IdeaPad-3-15ITL6:/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc# ./proc-uptime-001 proc-uptime-001: proc-uptime-001.c:39: main: Assertion `i1 >= i0' failed. Aborted (core dumped) root@marvin-IdeaPad-3-15ITL6:/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc# ./proc-uptime-001 proc-uptime-001: proc-uptime-001.c:39: main: Assertion `i1 >= i0' failed. Aborted (core dumped) root@marvin-IdeaPad-3-15ITL6:/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc# ./proc-uptime-001 proc-uptime-001: proc-uptime-001.c:39: main: Assertion `i1 >= i0' failed. Aborted (core dumped) root@marvin-IdeaPad-3-15ITL6:/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc# ./proc-uptime-001 It happens about half of the times the program is called. The source seems OK, I can't tell why the idle counter doesn't look monotonic to the program. Hope this helps. BTW, good news: this time I have checked independently, and this is the last test from the .../selftest/proc group that doesn't have clean exit code 0. 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
On 06. 01. 2023. 22:18, Mirsad Goran Todorovac wrote:
> Hi all,
>
> In the same environment as the previous bug report (Lenovo Ideapad 3 15ITL6 laptop
> running Ubuntu 22.10 kinetic kudu and 6.2-rc2 vanilla Torvalds tree kernel), the
> next test in the ...selftest/proc/* sequence spuriously fails in assert (i1 <= i0).
>
> Please note that the compiler is the novelty GCC 12.2.0-3ubuntu1.
>
> This was previously hidden by premature hang in the `make kselftest` run due to
> proc-empty-vm an proc-pid-vm problems that are now fixed.
>
> root@marvin-IdeaPad-3-15ITL6:/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc# ./proc-uptime-001
> root@marvin-IdeaPad-3-15ITL6:/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc# ./proc-uptime-001
> root@marvin-IdeaPad-3-15ITL6:/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc# ./proc-uptime-001
> proc-uptime-001: proc-uptime-001.c:39: main: Assertion `i1 >= i0' failed.
> Aborted (core dumped)
> root@marvin-IdeaPad-3-15ITL6:/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc# ./proc-uptime-001
> proc-uptime-001: proc-uptime-001.c:39: main: Assertion `i1 >= i0' failed.
> Aborted (core dumped)
> root@marvin-IdeaPad-3-15ITL6:/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc# ./proc-uptime-001
> root@marvin-IdeaPad-3-15ITL6:/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc# ./proc-uptime-001
> root@marvin-IdeaPad-3-15ITL6:/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc# ./proc-uptime-001
> root@marvin-IdeaPad-3-15ITL6:/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc# ./proc-uptime-001
> root@marvin-IdeaPad-3-15ITL6:/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc# ./proc-uptime-001
> proc-uptime-001: proc-uptime-001.c:39: main: Assertion `i1 >= i0' failed.
> Aborted (core dumped)
> root@marvin-IdeaPad-3-15ITL6:/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc# ./proc-uptime-001
> root@marvin-IdeaPad-3-15ITL6:/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc# ./proc-uptime-001
> proc-uptime-001: proc-uptime-001.c:39: main: Assertion `i1 >= i0' failed.
> Aborted (core dumped)
> root@marvin-IdeaPad-3-15ITL6:/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc# ./proc-uptime-001
> root@marvin-IdeaPad-3-15ITL6:/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc# ./proc-uptime-001
> proc-uptime-001: proc-uptime-001.c:39: main: Assertion `i1 >= i0' failed.
> Aborted (core dumped)
> root@marvin-IdeaPad-3-15ITL6:/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc# ./proc-uptime-001
> root@marvin-IdeaPad-3-15ITL6:/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc# ./proc-uptime-001
> root@marvin-IdeaPad-3-15ITL6:/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc# ./proc-uptime-001
> proc-uptime-001: proc-uptime-001.c:39: main: Assertion `i1 >= i0' failed.
> Aborted (core dumped)
> root@marvin-IdeaPad-3-15ITL6:/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc# ./proc-uptime-001
> proc-uptime-001: proc-uptime-001.c:39: main: Assertion `i1 >= i0' failed.
> Aborted (core dumped)
> root@marvin-IdeaPad-3-15ITL6:/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc# ./proc-uptime-001
> proc-uptime-001: proc-uptime-001.c:39: main: Assertion `i1 >= i0' failed.
> Aborted (core dumped)
> root@marvin-IdeaPad-3-15ITL6:/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc# ./proc-uptime-001
> proc-uptime-001: proc-uptime-001.c:39: main: Assertion `i1 >= i0' failed.
> Aborted (core dumped)
> root@marvin-IdeaPad-3-15ITL6:/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc# ./proc-uptime-001
> proc-uptime-001: proc-uptime-001.c:39: main: Assertion `i1 >= i0' failed.
> Aborted (core dumped)
> root@marvin-IdeaPad-3-15ITL6:/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc# ./proc-uptime-001
> proc-uptime-001: proc-uptime-001.c:39: main: Assertion `i1 >= i0' failed.
> Aborted (core dumped)
> root@marvin-IdeaPad-3-15ITL6:/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc# ./proc-uptime-001
>
> It happens about half of the times the program is called.
>
> The source seems OK, I can't tell why the idle counter doesn't look monotonic to
> the program.
>
> Hope this helps.
>
> BTW, good news: this time I have checked independently, and this is the last test from the .../selftest/proc
> group that doesn't have clean exit code 0.
UPDATE:
The same behavior independently occurred with GCC 10.4.0, 9.5.0, 8.5.0 and 6.5.0.
Apparently this happens in 30% to 50% of attempts. Perhaps that's why it wasn't discovered yet:
root@marvin-IdeaPad-3-15ITL6:/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc# make CC=gcc-10
gcc-10 -Wall -O2 -Wno-unused-function -D_GNU_SOURCE -pthread fd-001-lookup.c -o
/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc/fd-001-lookup
gcc-10 -Wall -O2 -Wno-unused-function -D_GNU_SOURCE -pthread fd-002-posix-eq.c -o
/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc/fd-002-posix-eq
gcc-10 -Wall -O2 -Wno-unused-function -D_GNU_SOURCE -pthread fd-003-kthread.c -o
/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc/fd-003-kthread
gcc-10 -Wall -O2 -Wno-unused-function -D_GNU_SOURCE -pthread proc-loadavg-001.c -o
/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc/proc-loadavg-001
gcc-10 -Wall -O2 -Wno-unused-function -D_GNU_SOURCE -pthread proc-empty-vm.c -o
/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc/proc-empty-vm
gcc-10 -Wall -O2 -Wno-unused-function -D_GNU_SOURCE -pthread proc-pid-vm.c -o
/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc/proc-pid-vm
gcc-10 -Wall -O2 -Wno-unused-function -D_GNU_SOURCE -pthread proc-self-map-files-001.c -o
/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc/proc-self-map-files-001
gcc-10 -Wall -O2 -Wno-unused-function -D_GNU_SOURCE -pthread proc-self-map-files-002.c -o
/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc/proc-self-map-files-002
gcc-10 -Wall -O2 -Wno-unused-function -D_GNU_SOURCE -pthread proc-self-syscall.c -o
/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc/proc-self-syscall
gcc-10 -Wall -O2 -Wno-unused-function -D_GNU_SOURCE -pthread proc-self-wchan.c -o
/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc/proc-self-wchan
gcc-10 -Wall -O2 -Wno-unused-function -D_GNU_SOURCE -pthread proc-subset-pid.c -o
/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc/proc-subset-pid
gcc-10 -Wall -O2 -Wno-unused-function -D_GNU_SOURCE -pthread proc-tid0.c -o
/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc/proc-tid0
gcc-10 -Wall -O2 -Wno-unused-function -D_GNU_SOURCE -pthread proc-uptime-001.c -o
/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc/proc-uptime-001
gcc-10 -Wall -O2 -Wno-unused-function -D_GNU_SOURCE -pthread proc-uptime-002.c -o
/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc/proc-uptime-002
gcc-10 -Wall -O2 -Wno-unused-function -D_GNU_SOURCE -pthread read.c -o
/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc/read
gcc-10 -Wall -O2 -Wno-unused-function -D_GNU_SOURCE -pthread self.c -o
/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc/self
gcc-10 -Wall -O2 -Wno-unused-function -D_GNU_SOURCE -pthread setns-dcache.c -o
/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc/setns-dcache
gcc-10 -Wall -O2 -Wno-unused-function -D_GNU_SOURCE -pthread setns-sysvipc.c -o
/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc/setns-sysvipc
gcc-10 -Wall -O2 -Wno-unused-function -D_GNU_SOURCE -pthread thread-self.c -o
/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc/thread-self
gcc-10 -Wall -O2 -Wno-unused-function -D_GNU_SOURCE -pthread proc-multiple-procfs.c -o
/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc/proc-multiple-procfs
gcc-10 -Wall -O2 -Wno-unused-function -D_GNU_SOURCE -pthread proc-fsconfig-hidepid.c -o
/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc/proc-fsconfig-hidepid
root@marvin-IdeaPad-3-15ITL6:/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc# for exe in `ls -l | grep -e -x |
awk '{ print $9 }'`; do echo -n ${exe}':'; ./$exe ; echo "exit=$?" ; done
fd-001-lookup:exit=0
fd-002-posix-eq:exit=0
fd-003-kthread:exit=0
proc-empty-vm:exit=0
proc-fsconfig-hidepid:exit=0
proc-loadavg-001:exit=0
proc-multiple-procfs:exit=0
proc-pid-vm:exit=0
proc-self-map-files-001:exit=0
proc-self-map-files-002:exit=0
proc-self-syscall:exit=0
proc-self-wchan:exit=0
proc-subset-pid:exit=0
proc-tid0:exit=0
proc-uptime-001:exit=0
proc-uptime-002:exit=0
read:exit=0
self:exit=0
setns-dcache:exit=0
setns-sysvipc:exit=0
thread-self:exit=0
root@marvin-IdeaPad-3-15ITL6:/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc# ./proc-uptime-001
proc-uptime-001: proc-uptime-001.c:39: main: Assertion `i1 >= i0' failed.
Aborted (core dumped)
root@marvin-IdeaPad-3-15ITL6:/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc# ./proc-uptime-001
root@marvin-IdeaPad-3-15ITL6:/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc# ./proc-uptime-001
root@marvin-IdeaPad-3-15ITL6:/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc# ./proc-uptime-001
root@marvin-IdeaPad-3-15ITL6:/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc# ./proc-uptime-001
root@marvin-IdeaPad-3-15ITL6:/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc# ./proc-uptime-001
proc-uptime-001: proc-uptime-001.c:39: main: Assertion `i1 >= i0' failed.
Aborted (core dumped)
root@marvin-IdeaPad-3-15ITL6:/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc# ./proc-uptime-001
root@marvin-IdeaPad-3-15ITL6:/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc# ./proc-uptime-001
proc-uptime-001: proc-uptime-001.c:39: main: Assertion `i1 >= i0' failed.
Aborted (core dumped)
root@marvin-IdeaPad-3-15ITL6:/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc# ./proc-uptime-001
root@marvin-IdeaPad-3-15ITL6:/home/marvin/linux/kernel/linux_torvalds/tools/testing/selftests/proc# ./proc-uptime-001
The conclusion (to state the obvious) is that the GCC 12.2.0 optimisations are
not the culprit this time :-/
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
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@gmail.com>
> Reported-by: Mirsad Goran Todorovac <mirsad.todorovac@alu.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
© 2016 - 2026 Red Hat, Inc.