arm64: add prctl control for resetting ptrauth keys
Add an arm64-specific prctl to allow a thread to reinitialize its pointer authentication keys to random values. This can be useful when exec() is not used for starting new processes, to ensure that different processes still have different keys. Signed-off-by: Kristina Martsenko <kristina.martsenko@arm.com> Signed-off-by: Will Deacon <will.deacon@arm.com>
This commit is contained in:

committed by
Will Deacon

parent
ccc4381082
commit
ba83088565
@@ -58,6 +58,7 @@ arm64-obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
|
||||
arm64-obj-$(CONFIG_CRASH_CORE) += crash_core.o
|
||||
arm64-obj-$(CONFIG_ARM_SDE_INTERFACE) += sdei.o
|
||||
arm64-obj-$(CONFIG_ARM64_SSBD) += ssbd.o
|
||||
arm64-obj-$(CONFIG_ARM64_PTR_AUTH) += pointer_auth.o
|
||||
|
||||
obj-y += $(arm64-obj-y) vdso/ probes/
|
||||
obj-m += $(arm64-obj-m)
|
||||
|
47
arch/arm64/kernel/pointer_auth.c
Normal file
47
arch/arm64/kernel/pointer_auth.c
Normal file
@@ -0,0 +1,47 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
#include <linux/errno.h>
|
||||
#include <linux/prctl.h>
|
||||
#include <linux/random.h>
|
||||
#include <linux/sched.h>
|
||||
#include <asm/cpufeature.h>
|
||||
#include <asm/pointer_auth.h>
|
||||
|
||||
int ptrauth_prctl_reset_keys(struct task_struct *tsk, unsigned long arg)
|
||||
{
|
||||
struct ptrauth_keys *keys = &tsk->thread_info.keys_user;
|
||||
unsigned long addr_key_mask = PR_PAC_APIAKEY | PR_PAC_APIBKEY |
|
||||
PR_PAC_APDAKEY | PR_PAC_APDBKEY;
|
||||
unsigned long key_mask = addr_key_mask | PR_PAC_APGAKEY;
|
||||
|
||||
if (!system_supports_address_auth() && !system_supports_generic_auth())
|
||||
return -EINVAL;
|
||||
|
||||
if (!arg) {
|
||||
ptrauth_keys_init(keys);
|
||||
ptrauth_keys_switch(keys);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (arg & ~key_mask)
|
||||
return -EINVAL;
|
||||
|
||||
if (((arg & addr_key_mask) && !system_supports_address_auth()) ||
|
||||
((arg & PR_PAC_APGAKEY) && !system_supports_generic_auth()))
|
||||
return -EINVAL;
|
||||
|
||||
if (arg & PR_PAC_APIAKEY)
|
||||
get_random_bytes(&keys->apia, sizeof(keys->apia));
|
||||
if (arg & PR_PAC_APIBKEY)
|
||||
get_random_bytes(&keys->apib, sizeof(keys->apib));
|
||||
if (arg & PR_PAC_APDAKEY)
|
||||
get_random_bytes(&keys->apda, sizeof(keys->apda));
|
||||
if (arg & PR_PAC_APDBKEY)
|
||||
get_random_bytes(&keys->apdb, sizeof(keys->apdb));
|
||||
if (arg & PR_PAC_APGAKEY)
|
||||
get_random_bytes(&keys->apga, sizeof(keys->apga));
|
||||
|
||||
ptrauth_keys_switch(keys);
|
||||
|
||||
return 0;
|
||||
}
|
Reference in New Issue
Block a user