diff options
-rw-r--r-- | tools/testing/selftests/x86/protection_keys.c | 44 |
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 | ||
1306 | void 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 | |||
1306 | void test_mprotect_pkey_on_unsupported_cpu(int *ptr, u16 pkey) | 1349 | void 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, |