Implement the Morello-specific aspects of linux/cheri.h, that is:
* Override standard permission sets to include the appropriate Morello-specific permissions.
* Initialise the global root capabilities appropriately.
Signed-off-by: Kevin Brodsky kevin.brodsky@arm.com --- arch/arm64/Kconfig | 1 + arch/arm64/include/asm/cheri.h | 14 ++++++++++++ arch/arm64/kernel/morello.c | 39 +++++++++++++++++++++++++++------- 3 files changed, 46 insertions(+), 8 deletions(-) create mode 100644 arch/arm64/include/asm/cheri.h
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index d402721ccad0..a0635a459a67 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -29,6 +29,7 @@ config ARM64 select ARCH_HAS_GCOV_PROFILE_ALL select ARCH_HAS_GIGANTIC_PAGE select ARCH_HAS_KCOV + select ARCH_HAS_CHERI_H select ARCH_HAS_USER_PTR_H select ARCH_HAS_KEEPINITRD select ARCH_HAS_MEMBARRIER_SYNC_CORE diff --git a/arch/arm64/include/asm/cheri.h b/arch/arm64/include/asm/cheri.h new file mode 100644 index 000000000000..c35c17cb4b6a --- /dev/null +++ b/arch/arm64/include/asm/cheri.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef __ASM_CHERI_H +#define __ASM_CHERI_H + +#define CHERI_PERMS_READ \ + (CHERI_PERM_LOAD | CHERI_PERM_LOAD_CAP | ARM_CAP_PERMISSION_MUTABLE_LOAD) + +#define CHERI_PERMS_EXEC \ + (CHERI_PERM_EXECUTE | CHERI_PERM_SYSTEM_REGS | ARM_CAP_PERMISSION_EXECUTIVE) + +#define CHERI_PERMS_ROOTCAP \ + (CHERI_PERM_GLOBAL | CHERI_PERM_SW_VMEM | ARM_CAP_PERMISSION_BRANCH_SEALED_PAIR) + +#endif /* __ASM_CHERI_H */ diff --git a/arch/arm64/kernel/morello.c b/arch/arm64/kernel/morello.c index ccbf26e77919..a9f2c0f1e56e 100644 --- a/arch/arm64/kernel/morello.c +++ b/arch/arm64/kernel/morello.c @@ -5,10 +5,9 @@
#define pr_fmt(fmt) "morello: " fmt
-#include <cheriintrin.h> - #include <linux/cache.h> #include <linux/capability.h> +#include <linux/cheri.h> #include <linux/compat.h> #include <linux/mm.h> #include <linux/printk.h> @@ -307,17 +306,41 @@ static void __init check_root_cap(uintcap_t cap)
static int __init morello_cap_init(void) { -#ifdef CONFIG_CHERI_PURECAP_UABI - uintcap_t ctemp; -#endif + uintcap_t root_cap, ctemp; + + root_cap = (uintcap_t)cheri_ddc_get(); + check_root_cap(root_cap); + + /* Initialise standard CHERI root capabilities. */ + ctemp = cheri_address_set(root_cap, 0); + /* Same upper limit as for access_ok() and __uaccess_mask_ptr() */ + ctemp = cheri_bounds_set(ctemp, TASK_SIZE_MAX); + ctemp = cheri_perms_and(ctemp, CHERI_PERMS_ROOTCAP | CHERI_PERMS_READ | + CHERI_PERMS_WRITE | CHERI_PERMS_EXEC); + cheri_root_cap_userspace = ctemp; + + ctemp = cheri_address_set(root_cap, 0); + /* + * All object types, not a final decision - some of them may be later + * reserved to the kernel. + */ + ctemp = cheri_bounds_set(ctemp, 1u << 15); + ctemp = cheri_perms_and(ctemp, CHERI_PERM_GLOBAL | + CHERI_PERM_SEAL | CHERI_PERM_UNSEAL); + cheri_root_seal_cap_userspace = ctemp;
- morello_root_cap = (uintcap_t)cheri_ddc_get(); + /* Maximum bounds for the time being. */ + ctemp = root_cap; + ctemp = cheri_perms_and(ctemp, CHERI_PERM_GLOBAL | + ARM_CAP_PERMISSION_COMPARTMENT_ID); + cheri_root_cid_cap_userspace = ctemp;
- check_root_cap(morello_root_cap); + /* Initialise Morello-specific root capabilities. */ + morello_root_cap = root_cap;
#ifdef CONFIG_CHERI_PURECAP_UABI /* Initialize a capability able to unseal sentry capabilities. */ - ctemp = cheri_address_set(morello_root_cap, CHERI_OTYPE_SENTRY); + ctemp = cheri_address_set(root_cap, CHERI_OTYPE_SENTRY); ctemp = cheri_bounds_set(ctemp, 1); ctemp = cheri_perms_and(ctemp, CHERI_PERM_GLOBAL | CHERI_PERM_UNSEAL); morello_sentry_unsealcap = ctemp;