Skip to content

Commit 3fabb43

Browse files
mrutland-armctmarinas
authored andcommitted
arm64: sync kernel APIAKey when installing
A direct write to a APxxKey_EL1 register requires a context synchronization event to ensure that indirect reads made by subsequent instructions (e.g. AUTIASP, PACIASP) observe the new value. When we initialize the boot task's APIAKey in boot_init_stack_canary() via ptrauth_keys_switch_kernel() we miss the necessary ISB, and so there is a window where instructions are not guaranteed to use the new APIAKey value. This has been observed to result in boot-time crashes where PACIASP and AUTIASP within a function used a mixture of the old and new key values. Fix this by having ptrauth_keys_switch_kernel() synchronize the new key value with an ISB. At the same time, __ptrauth_key_install() is renamed to __ptrauth_key_install_nosync() so that it is obvious that this performs no synchronization itself. Fixes: 2832158 ("arm64: initialize ptrauth keys for kernel booting task") Signed-off-by: Mark Rutland <[email protected]> Reported-by: Will Deacon <[email protected]> Cc: Amit Daniel Kachhap <[email protected]> Cc: Marc Zyngier <[email protected]> Signed-off-by: Catalin Marinas <[email protected]> Tested-by: Will Deacon <[email protected]>
1 parent ae83d0b commit 3fabb43

File tree

1 file changed

+6
-3
lines changed

1 file changed

+6
-3
lines changed

arch/arm64/include/asm/pointer_auth.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ static inline void ptrauth_keys_init_user(struct ptrauth_keys_user *keys)
4747
get_random_bytes(&keys->apga, sizeof(keys->apga));
4848
}
4949

50-
#define __ptrauth_key_install(k, v) \
50+
#define __ptrauth_key_install_nosync(k, v) \
5151
do { \
5252
struct ptrauth_key __pki_v = (v); \
5353
write_sysreg_s(__pki_v.lo, SYS_ ## k ## KEYLO_EL1); \
@@ -62,8 +62,11 @@ static __always_inline void ptrauth_keys_init_kernel(struct ptrauth_keys_kernel
6262

6363
static __always_inline void ptrauth_keys_switch_kernel(struct ptrauth_keys_kernel *keys)
6464
{
65-
if (system_supports_address_auth())
66-
__ptrauth_key_install(APIA, keys->apia);
65+
if (!system_supports_address_auth())
66+
return;
67+
68+
__ptrauth_key_install_nosync(APIA, keys->apia);
69+
isb();
6770
}
6871

6972
extern int ptrauth_prctl_reset_keys(struct task_struct *tsk, unsigned long arg);

0 commit comments

Comments
 (0)