aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorDave Hansen <dave.hansen@linux.intel.com>2018-05-09 13:13:48 -0400
committerIngo Molnar <mingo@kernel.org>2018-05-14 05:14:45 -0400
commit6af17cf89e99b64cf1f660bf848755442ab2f047 (patch)
treea7ce9d60f1c483892d161307217d6dcffb4f8c52 /tools
parent3fcd2b2d928904cbf30b01e2c5e4f1dd2f9ab262 (diff)
x86/pkeys/selftests: Add PROT_EXEC test
Under the covers, implement executable-only memory with protection keys when userspace calls mprotect(PROT_EXEC). But, we did not have a selftest for that. Now we do. Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Dave Hansen <dave.hansen@intel.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Michael Ellermen <mpe@ellerman.id.au> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Ram Pai <linuxram@us.ibm.com> Cc: Shuah Khan <shuah@kernel.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: linux-mm@kvack.org Link: http://lkml.kernel.org/r/20180509171348.9EEE4BEF@viggo.jf.intel.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'tools')
-rw-r--r--tools/testing/selftests/x86/protection_keys.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/tools/testing/selftests/x86/protection_keys.c b/tools/testing/selftests/x86/protection_keys.c
index 083ebd51b44e..8cb4fe58f381 100644
--- a/tools/testing/selftests/x86/protection_keys.c
+++ b/tools/testing/selftests/x86/protection_keys.c
@@ -1303,6 +1303,49 @@ void test_executing_on_unreadable_memory(int *ptr, u16 pkey)
1303 expected_pk_fault(pkey); 1303 expected_pk_fault(pkey);
1304} 1304}
1305 1305
1306void test_implicit_mprotect_exec_only_memory(int *ptr, u16 pkey)
1307{
1308 void *p1;
1309 int scratch;
1310 int ptr_contents;
1311 int ret;
1312
1313 dprintf1("%s() start\n", __func__);
1314
1315 p1 = get_pointer_to_instructions();
1316 lots_o_noops_around_write(&scratch);
1317 ptr_contents = read_ptr(p1);
1318 dprintf2("ptr (%p) contents@%d: %x\n", p1, __LINE__, ptr_contents);
1319
1320 /* Use a *normal* mprotect(), not mprotect_pkey(): */
1321 ret = mprotect(p1, PAGE_SIZE, PROT_EXEC);
1322 pkey_assert(!ret);
1323
1324 dprintf2("pkru: %x\n", rdpkru());
1325
1326 /* Make sure this is an *instruction* fault */
1327 madvise(p1, PAGE_SIZE, MADV_DONTNEED);
1328 lots_o_noops_around_write(&scratch);
1329 do_not_expect_pk_fault("executing on PROT_EXEC memory");
1330 ptr_contents = read_ptr(p1);
1331 dprintf2("ptr (%p) contents@%d: %x\n", p1, __LINE__, ptr_contents);
1332 expected_pk_fault(UNKNOWN_PKEY);
1333
1334 /*
1335 * Put the memory back to non-PROT_EXEC. Should clear the
1336 * exec-only pkey off the VMA and allow it to be readable
1337 * again. Go to PROT_NONE first to check for a kernel bug
1338 * that did not clear the pkey when doing PROT_NONE.
1339 */
1340 ret = mprotect(p1, PAGE_SIZE, PROT_NONE);
1341 pkey_assert(!ret);
1342
1343 ret = mprotect(p1, PAGE_SIZE, PROT_READ|PROT_EXEC);
1344 pkey_assert(!ret);
1345 ptr_contents = read_ptr(p1);
1346 do_not_expect_pk_fault("plain read on recently PROT_EXEC area");
1347}
1348
1306void test_mprotect_pkey_on_unsupported_cpu(int *ptr, u16 pkey) 1349void test_mprotect_pkey_on_unsupported_cpu(int *ptr, u16 pkey)
1307{ 1350{
1308 int size = PAGE_SIZE; 1351 int size = PAGE_SIZE;
@@ -1327,6 +1370,7 @@ void (*pkey_tests[])(int *ptr, u16 pkey) = {
1327 test_kernel_gup_of_access_disabled_region, 1370 test_kernel_gup_of_access_disabled_region,
1328 test_kernel_gup_write_to_write_disabled_region, 1371 test_kernel_gup_write_to_write_disabled_region,
1329 test_executing_on_unreadable_memory, 1372 test_executing_on_unreadable_memory,
1373 test_implicit_mprotect_exec_only_memory,
1330 test_ptrace_of_child, 1374 test_ptrace_of_child,
1331 test_pkey_syscalls_on_non_allocated_pkey, 1375 test_pkey_syscalls_on_non_allocated_pkey,
1332 test_pkey_syscalls_bad_args, 1376 test_pkey_syscalls_bad_args,