@@ -147,7 +147,7 @@ void abort_hooks(void)
147147 * will then fault, which makes sure that the fault code handles
148148 * execute-only memory properly.
149149 */
150- #ifdef __powerpc64__
150+ #if defined( __powerpc64__ ) || defined( __aarch64__ )
151151/* This way, both 4K and 64K alignment are maintained */
152152__attribute__((__aligned__ (65536 )))
153153#else
@@ -212,7 +212,6 @@ void pkey_disable_set(int pkey, int flags)
212212 unsigned long syscall_flags = 0 ;
213213 int ret ;
214214 int pkey_rights ;
215- u64 orig_pkey_reg = read_pkey_reg ();
216215
217216 dprintf1 ("START->%s(%d, 0x%x)\n" , __func__ ,
218217 pkey , flags );
@@ -242,8 +241,6 @@ void pkey_disable_set(int pkey, int flags)
242241
243242 dprintf1 ("%s(%d) pkey_reg: 0x%016llx\n" ,
244243 __func__ , pkey , read_pkey_reg ());
245- if (flags )
246- pkey_assert (read_pkey_reg () >= orig_pkey_reg );
247244 dprintf1 ("END<---%s(%d, 0x%x)\n" , __func__ ,
248245 pkey , flags );
249246}
@@ -253,7 +250,6 @@ void pkey_disable_clear(int pkey, int flags)
253250 unsigned long syscall_flags = 0 ;
254251 int ret ;
255252 int pkey_rights = hw_pkey_get (pkey , syscall_flags );
256- u64 orig_pkey_reg = read_pkey_reg ();
257253
258254 pkey_assert (flags & (PKEY_DISABLE_ACCESS | PKEY_DISABLE_WRITE ));
259255
@@ -273,8 +269,6 @@ void pkey_disable_clear(int pkey, int flags)
273269
274270 dprintf1 ("%s(%d) pkey_reg: 0x%016llx\n" , __func__ ,
275271 pkey , read_pkey_reg ());
276- if (flags )
277- assert (read_pkey_reg () <= orig_pkey_reg );
278272}
279273
280274void pkey_write_allow (int pkey )
@@ -330,8 +324,8 @@ void signal_handler(int signum, siginfo_t *si, void *vucontext)
330324 __func__ , __LINE__ ,
331325 __read_pkey_reg (), shadow_pkey_reg );
332326
333- trapno = uctxt -> uc_mcontext . gregs [ REG_TRAPNO ] ;
334- ip = uctxt -> uc_mcontext . gregs [ REG_IP_IDX ] ;
327+ trapno = MCONTEXT_TRAPNO ( uctxt -> uc_mcontext ) ;
328+ ip = MCONTEXT_IP ( uctxt -> uc_mcontext ) ;
335329#ifdef MCONTEXT_FPREGS
336330 fpregs = (char * ) uctxt -> uc_mcontext .fpregs ;
337331#endif
@@ -395,6 +389,8 @@ void signal_handler(int signum, siginfo_t *si, void *vucontext)
395389#elif defined(__powerpc64__ ) /* arch */
396390 /* restore access and let the faulting instruction continue */
397391 pkey_access_allow (siginfo_pkey );
392+ #elif defined(__aarch64__ )
393+ aarch64_write_signal_pkey (uctxt , PKEY_ALLOW_ALL );
398394#endif /* arch */
399395 pkey_faults ++ ;
400396 dprintf1 ("<<<<==================================================\n" );
@@ -908,7 +904,9 @@ void expected_pkey_fault(int pkey)
908904 * test program continue. We now have to restore it.
909905 */
910906 if (__read_pkey_reg () != 0 )
911- #else /* arch */
907+ #elif defined(__aarch64__ )
908+ if (__read_pkey_reg () != PKEY_ALLOW_ALL )
909+ #else
912910 if (__read_pkey_reg () != shadow_pkey_reg )
913911#endif /* arch */
914912 pkey_assert (0 );
@@ -1498,6 +1496,11 @@ void test_executing_on_unreadable_memory(int *ptr, u16 pkey)
14981496 lots_o_noops_around_write (& scratch );
14991497 do_not_expect_pkey_fault ("executing on PROT_EXEC memory" );
15001498 expect_fault_on_read_execonly_key (p1 , pkey );
1499+
1500+ // Reset back to PROT_EXEC | PROT_READ for architectures that support
1501+ // non-PKEY execute-only permissions.
1502+ ret = mprotect_pkey (p1 , PAGE_SIZE , PROT_EXEC | PROT_READ , (u64 )pkey );
1503+ pkey_assert (!ret );
15011504}
15021505
15031506void test_implicit_mprotect_exec_only_memory (int * ptr , u16 pkey )
@@ -1671,6 +1674,84 @@ void test_ptrace_modifies_pkru(int *ptr, u16 pkey)
16711674}
16721675#endif
16731676
1677+ #if defined(__aarch64__ )
1678+ void test_ptrace_modifies_pkru (int * ptr , u16 pkey )
1679+ {
1680+ pid_t child ;
1681+ int status , ret ;
1682+ struct iovec iov ;
1683+ u64 trace_pkey ;
1684+ /* Just a random pkey value.. */
1685+ u64 new_pkey = (POE_X << PKEY_BITS_PER_PKEY * 2 ) |
1686+ (POE_NONE << PKEY_BITS_PER_PKEY ) |
1687+ POE_RWX ;
1688+
1689+ child = fork ();
1690+ pkey_assert (child >= 0 );
1691+ dprintf3 ("[%d] fork() ret: %d\n" , getpid (), child );
1692+ if (!child ) {
1693+ ptrace (PTRACE_TRACEME , 0 , 0 , 0 );
1694+
1695+ /* Stop and allow the tracer to modify PKRU directly */
1696+ raise (SIGSTOP );
1697+
1698+ /*
1699+ * need __read_pkey_reg() version so we do not do shadow_pkey_reg
1700+ * checking
1701+ */
1702+ if (__read_pkey_reg () != new_pkey )
1703+ exit (1 );
1704+
1705+ raise (SIGSTOP );
1706+
1707+ exit (0 );
1708+ }
1709+
1710+ pkey_assert (child == waitpid (child , & status , 0 ));
1711+ dprintf3 ("[%d] waitpid(%d) status: %x\n" , getpid (), child , status );
1712+ pkey_assert (WIFSTOPPED (status ) && WSTOPSIG (status ) == SIGSTOP );
1713+
1714+ iov .iov_base = & trace_pkey ;
1715+ iov .iov_len = 8 ;
1716+ ret = ptrace (PTRACE_GETREGSET , child , (void * )NT_ARM_POE , & iov );
1717+ pkey_assert (ret == 0 );
1718+ pkey_assert (trace_pkey == read_pkey_reg ());
1719+
1720+ trace_pkey = new_pkey ;
1721+
1722+ ret = ptrace (PTRACE_SETREGSET , child , (void * )NT_ARM_POE , & iov );
1723+ pkey_assert (ret == 0 );
1724+
1725+ /* Test that the modification is visible in ptrace before any execution */
1726+ memset (& trace_pkey , 0 , sizeof (trace_pkey ));
1727+ ret = ptrace (PTRACE_GETREGSET , child , (void * )NT_ARM_POE , & iov );
1728+ pkey_assert (ret == 0 );
1729+ pkey_assert (trace_pkey == new_pkey );
1730+
1731+ /* Execute the tracee */
1732+ ret = ptrace (PTRACE_CONT , child , 0 , 0 );
1733+ pkey_assert (ret == 0 );
1734+
1735+ /* Test that the tracee saw the PKRU value change */
1736+ pkey_assert (child == waitpid (child , & status , 0 ));
1737+ dprintf3 ("[%d] waitpid(%d) status: %x\n" , getpid (), child , status );
1738+ pkey_assert (WIFSTOPPED (status ) && WSTOPSIG (status ) == SIGSTOP );
1739+
1740+ /* Test that the modification is visible in ptrace after execution */
1741+ memset (& trace_pkey , 0 , sizeof (trace_pkey ));
1742+ ret = ptrace (PTRACE_GETREGSET , child , (void * )NT_ARM_POE , & iov );
1743+ pkey_assert (ret == 0 );
1744+ pkey_assert (trace_pkey == new_pkey );
1745+
1746+ ret = ptrace (PTRACE_CONT , child , 0 , 0 );
1747+ pkey_assert (ret == 0 );
1748+ pkey_assert (child == waitpid (child , & status , 0 ));
1749+ dprintf3 ("[%d] waitpid(%d) status: %x\n" , getpid (), child , status );
1750+ pkey_assert (WIFEXITED (status ));
1751+ pkey_assert (WEXITSTATUS (status ) == 0 );
1752+ }
1753+ #endif
1754+
16741755void test_mprotect_pkey_on_unsupported_cpu (int * ptr , u16 pkey )
16751756{
16761757 int size = PAGE_SIZE ;
@@ -1706,7 +1787,7 @@ void (*pkey_tests[])(int *ptr, u16 pkey) = {
17061787 test_pkey_syscalls_bad_args ,
17071788 test_pkey_alloc_exhaust ,
17081789 test_pkey_alloc_free_attach_pkey0 ,
1709- #if defined(__i386__ ) || defined (__x86_64__ )
1790+ #if defined(__i386__ ) || defined (__x86_64__ ) || defined ( __aarch64__ )
17101791 test_ptrace_modifies_pkru ,
17111792#endif
17121793};
0 commit comments