Message ID | 20200421121014.53120-1-mark.rutland@arm.com (mailing list archive) |
---|---|
State | Mainlined |
Commit | 3fabb43818c9bfe7c4084badfa21d4e8187021a6 |
Headers | show |
Series | arm64: sync kernel APIAKey when installing | expand |
On Tue, Apr 21, 2020 at 01:10:14PM +0100, Mark Rutland wrote: > 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: 28321582334c261c ("arm64: initialize ptrauth keys for kernel booting task") > Signed-off-by: Mark Rutland <mark.rutland@arm.com> > Reported-by: Will Deacon <will@kernel.org> > Cc: Amit Daniel Kachhap <amit.kachhap@arm.com> > Cc: Catalin Marinas <catalin.marinas@arm.com> > Cc: Marc Zyngier <maz@kernel.org> > --- > arch/arm64/include/asm/pointer_auth.h | 9 ++++++--- > 1 file changed, 6 insertions(+), 3 deletions(-) Tested-by: Will Deacon <will@kernel.org> Catalin -- please can you queue this for -rc3? Cheers, Will
On Tue, Apr 21, 2020 at 01:31:51PM +0100, Will Deacon wrote: > On Tue, Apr 21, 2020 at 01:10:14PM +0100, Mark Rutland wrote: > > 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: 28321582334c261c ("arm64: initialize ptrauth keys for kernel booting task") > > Signed-off-by: Mark Rutland <mark.rutland@arm.com> > > Reported-by: Will Deacon <will@kernel.org> > > Cc: Amit Daniel Kachhap <amit.kachhap@arm.com> > > Cc: Catalin Marinas <catalin.marinas@arm.com> > > Cc: Marc Zyngier <maz@kernel.org> > > --- > > arch/arm64/include/asm/pointer_auth.h | 9 ++++++--- > > 1 file changed, 6 insertions(+), 3 deletions(-) > > Tested-by: Will Deacon <will@kernel.org> > > Catalin -- please can you queue this for -rc3? I will. Thanks.
diff --git a/arch/arm64/include/asm/pointer_auth.h b/arch/arm64/include/asm/pointer_auth.h index 70c47156e54b..c6b4f0603024 100644 --- a/arch/arm64/include/asm/pointer_auth.h +++ b/arch/arm64/include/asm/pointer_auth.h @@ -47,7 +47,7 @@ static inline void ptrauth_keys_init_user(struct ptrauth_keys_user *keys) get_random_bytes(&keys->apga, sizeof(keys->apga)); } -#define __ptrauth_key_install(k, v) \ +#define __ptrauth_key_install_nosync(k, v) \ do { \ struct ptrauth_key __pki_v = (v); \ 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 static __always_inline void ptrauth_keys_switch_kernel(struct ptrauth_keys_kernel *keys) { - if (system_supports_address_auth()) - __ptrauth_key_install(APIA, keys->apia); + if (!system_supports_address_auth()) + return; + + __ptrauth_key_install_nosync(APIA, keys->apia); + isb(); } extern int ptrauth_prctl_reset_keys(struct task_struct *tsk, unsigned long arg);
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: 28321582334c261c ("arm64: initialize ptrauth keys for kernel booting task") Signed-off-by: Mark Rutland <mark.rutland@arm.com> Reported-by: Will Deacon <will@kernel.org> Cc: Amit Daniel Kachhap <amit.kachhap@arm.com> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Marc Zyngier <maz@kernel.org> --- arch/arm64/include/asm/pointer_auth.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)