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

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
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -54,12 +54,18 @@ do { \
	write_sysreg_s(__pki_v.hi, SYS_ ## k ## KEYHI_EL1);	\
} 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())
		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);

/*
@@ -78,12 +84,15 @@ static inline unsigned long ptrauth_strip_insn_pac(unsigned long ptr)
	ptrauth_keys_init_user(&(tsk)->thread.keys_user)
#define ptrauth_thread_init_kernel(tsk)					\
	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 */
#define ptrauth_prctl_reset_keys(tsk, arg)	(-EINVAL)
#define ptrauth_strip_insn_pac(lr)	(lr)
#define ptrauth_thread_init_user(tsk)
#define ptrauth_thread_init_kernel(tsk)
#define ptrauth_thread_switch_kernel(tsk)
#endif /* CONFIG_ARM64_PTR_AUTH */

#endif /* __ASM_POINTER_AUTH_H */
+5 −0
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@

#include <linux/random.h>
#include <linux/version.h>
#include <asm/pointer_auth.h>

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)
{
#if defined(CONFIG_STACKPROTECTOR)
	unsigned long canary;

	/* Try to get a semi random initial value. */
@@ -36,6 +38,9 @@ static __always_inline void boot_init_stack_canary(void)
	current->stack_canary = canary;
	if (!IS_ENABLED(CONFIG_STACKPROTECTOR_PER_TASK))
		__stack_chk_guard = current->stack_canary;
#endif
	ptrauth_thread_init_kernel(current);
	ptrauth_thread_switch_kernel(current);
}

#endif	/* _ASM_STACKPROTECTOR_H */
+1 −1
Original line number Diff line number Diff line
@@ -6,7 +6,7 @@
#include <linux/sched.h>
#include <linux/random.h>

#ifdef CONFIG_STACKPROTECTOR
#if defined(CONFIG_STACKPROTECTOR) || defined(CONFIG_ARM64_PTR_AUTH)
# include <asm/stackprotector.h>
#else
static inline void boot_init_stack_canary(void)