Commit 8891adc6 authored by Andy Lutomirski's avatar Andy Lutomirski Committed by Linus Torvalds

selftests/x86/test_vsyscall: Improve the process_vm_readv() test

The existing code accepted process_vm_readv() success or failure as long
as it didn't return garbage.  This is too weak: if the vsyscall page is
readable, then process_vm_readv() should succeed and, if the page is not
readable, then it should fail.
Signed-off-by: default avatarAndy Lutomirski <luto@kernel.org>
Signed-off-by: default avatarDave Hansen <dave.hansen@linux.intel.com>
Cc: x86@kernel.org
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Jann Horn <jannh@google.com>
Cc: John Hubbard <jhubbard@nvidia.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 9fa2dd94
...@@ -462,6 +462,17 @@ static int test_vsys_x(void) ...@@ -462,6 +462,17 @@ static int test_vsys_x(void)
return 0; return 0;
} }
/*
* Debuggers expect ptrace() to be able to peek at the vsyscall page.
* Use process_vm_readv() as a proxy for ptrace() to test this. We
* want it to work in the vsyscall=emulate case and to fail in the
* vsyscall=xonly case.
*
* It's worth noting that this ABI is a bit nutty. write(2) can't
* read from the vsyscall page on any kernel version or mode. The
* fact that ptrace() ever worked was a nice courtesy of old kernels,
* but the code to support it is fairly gross.
*/
static int test_process_vm_readv(void) static int test_process_vm_readv(void)
{ {
#ifdef __x86_64__ #ifdef __x86_64__
...@@ -477,8 +488,12 @@ static int test_process_vm_readv(void) ...@@ -477,8 +488,12 @@ static int test_process_vm_readv(void)
remote.iov_len = 4096; remote.iov_len = 4096;
ret = process_vm_readv(getpid(), &local, 1, &remote, 1, 0); ret = process_vm_readv(getpid(), &local, 1, &remote, 1, 0);
if (ret != 4096) { if (ret != 4096) {
printf("[OK]\tprocess_vm_readv() failed (ret = %d, errno = %d)\n", ret, errno); /*
return 0; * We expect process_vm_readv() to work if and only if the
* vsyscall page is readable.
*/
printf("[%s]\tprocess_vm_readv() failed (ret = %d, errno = %d)\n", vsyscall_map_r ? "FAIL" : "OK", ret, errno);
return vsyscall_map_r ? 1 : 0;
} }
if (vsyscall_map_r) { if (vsyscall_map_r) {
...@@ -488,6 +503,9 @@ static int test_process_vm_readv(void) ...@@ -488,6 +503,9 @@ static int test_process_vm_readv(void)
printf("[FAIL]\tIt worked but returned incorrect data\n"); printf("[FAIL]\tIt worked but returned incorrect data\n");
return 1; return 1;
} }
} else {
printf("[FAIL]\tprocess_rm_readv() succeeded, but it should have failed in this configuration\n");
return 1;
} }
#endif #endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment