Commit 28321582 authored by Amit Daniel Kachhap's avatar Amit Daniel Kachhap Committed by Catalin Marinas

arm64: initialize ptrauth keys for kernel booting task

This patch uses the existing boot_init_stack_canary arch function
to initialize the ptrauth keys for the booting task in the primary
core. The requirement here is that it should be always inline and
the caller must never return.

As pointer authentication too detects a subset of stack corruption
so it makes sense to place this code here.

Both pointer authentication and stack canary codes are protected
by their respective config option.
Suggested-by: default avatarArd Biesheuvel <ardb@kernel.org>
Signed-off-by: default avatarAmit Daniel Kachhap <amit.kachhap@arm.com>
Reviewed-by: default avatarVincenzo Frascino <Vincenzo.Frascino@arm.com>
Reviewed-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
parent 33e45234
...@@ -54,12 +54,18 @@ do { \ ...@@ -54,12 +54,18 @@ do { \
write_sysreg_s(__pki_v.hi, SYS_ ## k ## KEYHI_EL1); \ write_sysreg_s(__pki_v.hi, SYS_ ## k ## KEYHI_EL1); \
} while (0) } while (0)
static inline void ptrauth_keys_init_kernel(struct ptrauth_keys_kernel *keys) static __always_inline void ptrauth_keys_init_kernel(struct ptrauth_keys_kernel *keys)
{ {
if (system_supports_address_auth()) if (system_supports_address_auth())
get_random_bytes(&keys->apia, sizeof(keys->apia)); get_random_bytes(&keys->apia, sizeof(keys->apia));
} }
static __always_inline void ptrauth_keys_switch_kernel(struct ptrauth_keys_kernel *keys)
{
if (system_supports_address_auth())
__ptrauth_key_install(APIA, keys->apia);
}
extern int ptrauth_prctl_reset_keys(struct task_struct *tsk, unsigned long arg); extern int ptrauth_prctl_reset_keys(struct task_struct *tsk, unsigned long arg);
/* /*
...@@ -78,12 +84,15 @@ static inline unsigned long ptrauth_strip_insn_pac(unsigned long ptr) ...@@ -78,12 +84,15 @@ static inline unsigned long ptrauth_strip_insn_pac(unsigned long ptr)
ptrauth_keys_init_user(&(tsk)->thread.keys_user) ptrauth_keys_init_user(&(tsk)->thread.keys_user)
#define ptrauth_thread_init_kernel(tsk) \ #define ptrauth_thread_init_kernel(tsk) \
ptrauth_keys_init_kernel(&(tsk)->thread.keys_kernel) ptrauth_keys_init_kernel(&(tsk)->thread.keys_kernel)
#define ptrauth_thread_switch_kernel(tsk) \
ptrauth_keys_switch_kernel(&(tsk)->thread.keys_kernel)
#else /* CONFIG_ARM64_PTR_AUTH */ #else /* CONFIG_ARM64_PTR_AUTH */
#define ptrauth_prctl_reset_keys(tsk, arg) (-EINVAL) #define ptrauth_prctl_reset_keys(tsk, arg) (-EINVAL)
#define ptrauth_strip_insn_pac(lr) (lr) #define ptrauth_strip_insn_pac(lr) (lr)
#define ptrauth_thread_init_user(tsk) #define ptrauth_thread_init_user(tsk)
#define ptrauth_thread_init_kernel(tsk) #define ptrauth_thread_init_kernel(tsk)
#define ptrauth_thread_switch_kernel(tsk)
#endif /* CONFIG_ARM64_PTR_AUTH */ #endif /* CONFIG_ARM64_PTR_AUTH */
#endif /* __ASM_POINTER_AUTH_H */ #endif /* __ASM_POINTER_AUTH_H */
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <linux/random.h> #include <linux/random.h>
#include <linux/version.h> #include <linux/version.h>
#include <asm/pointer_auth.h>
extern unsigned long __stack_chk_guard; extern unsigned long __stack_chk_guard;
...@@ -26,6 +27,7 @@ extern unsigned long __stack_chk_guard; ...@@ -26,6 +27,7 @@ extern unsigned long __stack_chk_guard;
*/ */
static __always_inline void boot_init_stack_canary(void) static __always_inline void boot_init_stack_canary(void)
{ {
#if defined(CONFIG_STACKPROTECTOR)
unsigned long canary; unsigned long canary;
/* Try to get a semi random initial value. */ /* Try to get a semi random initial value. */
...@@ -36,6 +38,9 @@ static __always_inline void boot_init_stack_canary(void) ...@@ -36,6 +38,9 @@ static __always_inline void boot_init_stack_canary(void)
current->stack_canary = canary; current->stack_canary = canary;
if (!IS_ENABLED(CONFIG_STACKPROTECTOR_PER_TASK)) if (!IS_ENABLED(CONFIG_STACKPROTECTOR_PER_TASK))
__stack_chk_guard = current->stack_canary; __stack_chk_guard = current->stack_canary;
#endif
ptrauth_thread_init_kernel(current);
ptrauth_thread_switch_kernel(current);
} }
#endif /* _ASM_STACKPROTECTOR_H */ #endif /* _ASM_STACKPROTECTOR_H */
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/random.h> #include <linux/random.h>
#ifdef CONFIG_STACKPROTECTOR #if defined(CONFIG_STACKPROTECTOR) || defined(CONFIG_ARM64_PTR_AUTH)
# include <asm/stackprotector.h> # include <asm/stackprotector.h>
#else #else
static inline void boot_init_stack_canary(void) static inline void boot_init_stack_canary(void)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment