Skip to content

Commit

Permalink
Merge branch 'gate-page-refcount' (patches from Dave Hansen)
Browse files Browse the repository at this point in the history
Merge gate page refcount fix from Dave Hansen:
 "During the conversion over to pin_user_pages(), gate pages were missed.

  The fix is pretty simple, and is accompanied by a new test from Andy
  which probably would have caught this earlier"

* emailed patches from Dave Hansen <[email protected]>:
  selftests/x86/test_vsyscall: Improve the process_vm_readv() test
  mm: fix pin vs. gup mismatch with gate pages
  • Loading branch information
torvalds committed Sep 4, 2020
2 parents e28f010 + 8891adc commit 8381979
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 3 deletions.
2 changes: 1 addition & 1 deletion mm/gup.c
Original file line number Diff line number Diff line change
Expand Up @@ -843,7 +843,7 @@ static int get_gate_page(struct mm_struct *mm, unsigned long address,
goto unmap;
*page = pte_page(*pte);
}
if (unlikely(!try_get_page(*page))) {
if (unlikely(!try_grab_page(*page, gup_flags))) {
ret = -ENOMEM;
goto unmap;
}
Expand Down
22 changes: 20 additions & 2 deletions tools/testing/selftests/x86/test_vsyscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,17 @@ static int test_vsys_x(void)
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)
{
#ifdef __x86_64__
Expand All @@ -477,8 +488,12 @@ static int test_process_vm_readv(void)
remote.iov_len = 4096;
ret = process_vm_readv(getpid(), &local, 1, &remote, 1, 0);
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) {
Expand All @@ -488,6 +503,9 @@ static int test_process_vm_readv(void)
printf("[FAIL]\tIt worked but returned incorrect data\n");
return 1;
}
} else {
printf("[FAIL]\tprocess_rm_readv() succeeded, but it should have failed in this configuration\n");
return 1;
}
#endif

Expand Down

0 comments on commit 8381979

Please sign in to comment.