Lines Matching refs:pkey

7  *  * how to set/clear bits in pkey registers (the rights register)
8 * * how to handle SEGV_PKUERR signals and extract pkey-relevant
17 * look for pkey "leaks" where it is still set on a VMA but "freed" back to the kernel
18 * do a plain mprotect() to a mprotect_pkey() area and make sure the pkey sticks
48 #include "pkey-helpers.h"
177 static u32 hw_pkey_get(int pkey, unsigned long flags)
181 dprintf1("%s(pkey=%d, flags=%lx) = %x / %d\n",
182 __func__, pkey, flags, 0, 0);
185 return (u32) get_pkey_bits(pkey_reg, pkey);
188 static int hw_pkey_set(int pkey, unsigned long rights, unsigned long flags)
198 new_pkey_reg = set_pkey_bits(old_pkey_reg, pkey, rights);
202 dprintf3("%s(pkey=%d, rights=%lx, flags=%lx) = %x"
204 __func__, pkey, rights, flags, 0, __read_pkey_reg(),
209 void pkey_disable_set(int pkey, int flags)
217 pkey, flags);
220 pkey_rights = hw_pkey_get(pkey, syscall_flags);
223 pkey, pkey, pkey_rights);
229 ret = hw_pkey_set(pkey, pkey_rights, syscall_flags);
232 shadow_pkey_reg = set_pkey_bits(shadow_pkey_reg, pkey, pkey_rights);
234 __func__, pkey, shadow_pkey_reg);
238 pkey_rights = hw_pkey_get(pkey, syscall_flags);
240 pkey, pkey, pkey_rights);
243 __func__, pkey, read_pkey_reg());
247 pkey, flags);
250 void pkey_disable_clear(int pkey, int flags)
254 int pkey_rights = hw_pkey_get(pkey, syscall_flags);
260 pkey, pkey, pkey_rights);
265 ret = hw_pkey_set(pkey, pkey_rights, 0);
266 shadow_pkey_reg = set_pkey_bits(shadow_pkey_reg, pkey, pkey_rights);
269 pkey_rights = hw_pkey_get(pkey, syscall_flags);
271 pkey, pkey, pkey_rights);
274 pkey, read_pkey_reg());
279 void pkey_write_allow(int pkey)
281 pkey_disable_clear(pkey, PKEY_DISABLE_WRITE);
283 void pkey_write_deny(int pkey)
285 pkey_disable_set(pkey, PKEY_DISABLE_WRITE);
287 void pkey_access_allow(int pkey)
289 pkey_disable_clear(pkey, PKEY_DISABLE_ACCESS);
291 void pkey_access_deny(int pkey)
293 pkey_disable_set(pkey, PKEY_DISABLE_ACCESS);
392 dprintf1("pkey from siginfo: %016llx\n", siginfo_pkey);
470 unsigned long pkey)
474 dprintf2("%s(0x%p, %zx, prot=%lx, pkey=%lx)\n", __func__,
475 ptr, size, orig_prot, pkey);
478 sret = syscall(SYS_mprotect_key, ptr, size, orig_prot, pkey);
543 int sys_pkey_free(unsigned long pkey)
545 int ret = syscall(SYS_pkey_free, pkey);
546 dprintf1("%s(pkey=%ld) syscall ret: %d\n", __func__, pkey, ret);
551 * I had a bug where pkey bits could be set by mprotect() but
553 * and clears on the vma and pte pkey bits.
596 unsigned long pkey)
603 ret = sys_mprotect_pkey(ptr, size, orig_prot, pkey);
604 dprintf1("sys_mprotect_pkey(%p, %zx, prot=0x%lx, pkey=%ld) ret: %d\n",
605 ptr, size, orig_prot, pkey, ret);
619 pkey_assert(pkey < NR_PKEYS);
621 ret = sys_mprotect_pkey(ptr, size, orig_prot, pkey);
622 dprintf1("mprotect_pkey(%p, %zx, prot=0x%lx, pkey=%ld) ret: %d\n",
623 ptr, size, orig_prot, pkey, ret);
704 void *malloc_pkey_with_mprotect(long size, int prot, u16 pkey)
710 dprintf1("doing %s(size=%ld, prot=0x%x, pkey=%d)\n", __func__,
711 size, prot, pkey);
712 pkey_assert(pkey < NR_PKEYS);
715 ret = mprotect_pkey((void *)ptr, PAGE_SIZE, prot, pkey);
720 dprintf1("%s() for pkey %d @ %p\n", __func__, pkey, ptr);
724 void *malloc_pkey_anon_huge(long size, int prot, u16 pkey)
729 dprintf1("doing %s(size=%ld, prot=0x%x, pkey=%d)\n", __func__,
730 size, prot, pkey);
739 mprotect_pkey(ptr, size, prot, pkey);
750 dprintf1("mmap()'d thp for pkey %d @ %p\n", pkey, ptr);
805 void *malloc_pkey_hugetlb(long size, int prot, u16 pkey)
813 dprintf1("doing %s(%ld, %x, %x)\n", __func__, size, prot, pkey);
815 pkey_assert(pkey < NR_PKEYS);
818 mprotect_pkey(ptr, size, prot, pkey);
822 dprintf1("mmap()'d hugetlbfs for pkey %d @ %p\n", pkey, ptr);
826 void *malloc_pkey_mmap_dax(long size, int prot, u16 pkey)
831 dprintf1("doing %s(size=%ld, prot=0x%x, pkey=%d)\n", __func__,
832 size, prot, pkey);
833 pkey_assert(pkey < NR_PKEYS);
840 mprotect_pkey(ptr, size, prot, pkey);
844 dprintf1("mmap()'d for pkey %d @ %p\n", pkey, ptr);
849 void *(*pkey_malloc[])(long size, int prot, u16 pkey) = {
861 void *malloc_pkey(long size, int prot, u16 pkey)
867 pkey_assert(pkey < NR_PKEYS);
872 ret = pkey_malloc[malloc_type](size, prot, pkey);
886 dprintf3("%s(%ld, prot=%x, pkey=%x) returning: %p\n", __func__,
887 size, prot, pkey, ret);
893 void expected_pkey_fault(int pkey)
897 dprintf2("%s(%d): last_si_pkey: %d\n", __func__, pkey, last_si_pkey);
901 * For exec-only memory, we do not know the pkey in
904 if (pkey != UNKNOWN_PKEY)
905 pkey_assert(last_si_pkey == pkey);
971 void test_pkey_alloc_free_attach_pkey0(int *ptr, u16 pkey)
1023 void test_read_of_write_disabled_region(int *ptr, u16 pkey)
1028 pkey_write_deny(pkey);
1033 void test_read_of_access_disabled_region(int *ptr, u16 pkey)
1037 dprintf1("disabling access to PKEY[%02d], doing read @ %p\n", pkey, ptr);
1039 pkey_access_deny(pkey);
1042 expected_pkey_fault(pkey);
1046 u16 pkey)
1051 pkey, ptr);
1056 pkey_access_deny(pkey);
1059 expected_pkey_fault(pkey);
1063 u16 pkey)
1067 "to PKEY[%02d], doing write\n", pkey);
1068 pkey_write_deny(pkey);
1070 expected_pkey_fault(pkey);
1073 void test_write_of_write_disabled_region(int *ptr, u16 pkey)
1075 dprintf1("disabling write access to PKEY[%02d], doing write\n", pkey);
1076 pkey_write_deny(pkey);
1078 expected_pkey_fault(pkey);
1080 void test_write_of_access_disabled_region(int *ptr, u16 pkey)
1082 dprintf1("disabling access to PKEY[%02d], doing write\n", pkey);
1083 pkey_access_deny(pkey);
1085 expected_pkey_fault(pkey);
1089 u16 pkey)
1093 " to PKEY[%02d], doing write\n", pkey);
1094 pkey_access_deny(pkey);
1096 expected_pkey_fault(pkey);
1099 void test_kernel_write_of_access_disabled_region(int *ptr, u16 pkey)
1105 "having kernel read() to buffer\n", pkey);
1106 pkey_access_deny(pkey);
1111 void test_kernel_write_of_write_disabled_region(int *ptr, u16 pkey)
1116 pkey_write_deny(pkey);
1124 void test_kernel_gup_of_access_disabled_region(int *ptr, u16 pkey)
1134 "having kernel vmsplice from buffer\n", pkey);
1135 pkey_access_deny(pkey);
1146 void test_kernel_gup_write_to_write_disabled_region(int *ptr, u16 pkey)
1153 "doing futex gunk in buffer\n", pkey);
1155 pkey_write_deny(pkey);
1163 /* Assumes that all pkeys other than 'pkey' are unallocated */
1164 void test_pkey_syscalls_on_non_allocated_pkey(int *ptr, u16 pkey)
1169 /* Note: 0 is the default pkey, so don't mess with it */
1171 if (pkey == i)
1174 dprintf1("trying get/set/free to non-allocated pkey: %2d\n", i);
1186 /* Assumes that all pkeys other than 'pkey' are unallocated */
1187 void test_pkey_syscalls_bad_args(int *ptr, u16 pkey)
1192 /* pass a known-invalid pkey in: */
1212 /* Assumes that all pkeys other than 'pkey' are unallocated */
1213 void test_pkey_alloc_exhaust(int *ptr, u16 pkey)
1231 dprintf2("%s() failed to allocate pkey after %d tries\n",
1260 * 'pkey' to this function.
1267 * the time we get here. These include pkey-0, pkey-1,
1268 * exec-only pkey and the one allocated by the test code.
1281 * pkey 0 is special. It is allocated by default, so you do not
1285 void test_mprotect_with_pkey_0(int *ptr, u16 pkey)
1302 /* Use pkey 0 */
1305 /* Make sure that we can set it back to the original pkey. */
1306 mprotect_pkey(ptr, size, prot, pkey);
1309 void test_ptrace_of_child(int *ptr, u16 pkey)
1345 pkey_access_deny(pkey);
1346 pkey_write_deny(pkey);
1355 * Try to access the pkey-protected "ptr" via ptrace:
1362 expected_pkey_fault(pkey);
1365 * Try to access the NON-pkey-protected "plain_ptr" via ptrace:
1406 void test_executing_on_unreadable_memory(int *ptr, u16 pkey)
1418 ret = mprotect_pkey(p1, PAGE_SIZE, PROT_EXEC, (u64)pkey);
1420 pkey_access_deny(pkey);
1430 expect_fault_on_read_execonly_key(p1, pkey);
1433 void test_implicit_mprotect_exec_only_memory(int *ptr, u16 pkey)
1454 * the actual alllocated pkey is unknown.
1468 * exec-only pkey off the VMA and allow it to be readable
1470 * that did not clear the pkey when doing PROT_NONE.
1481 void test_mprotect_pkey_on_unsupported_cpu(int *ptr, u16 pkey)
1491 sret = syscall(SYS_mprotect_key, ptr, size, PROT_READ, pkey);
1495 void (*pkey_tests[])(int *ptr, u16 pkey) = {
1523 int pkey;
1530 pkey = alloc_random_pkey();
1531 dprintf1("test %d starting with pkey: %d\n", test_nr, pkey);
1532 ptr = malloc_pkey(PAGE_SIZE, prot, pkey);
1534 pkey_tests[test_nr](ptr, pkey);
1537 sys_pkey_free(pkey);