Hi,
On 12/12/22 16:05, Kevin Brodsky wrote:
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 | 11 +++++++ arch/arm64/kernel/morello.c | 58 ++++++++++++++++++++++++++-------- 3 files changed, 56 insertions(+), 14 deletions(-) create mode 100644 arch/arm64/include/asm/cheri.h
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index c784d8664a40..e5a330b1e0bd 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 HAVE_ARCH_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..eaae6ed88db5 --- /dev/null +++ b/arch/arm64/include/asm/cheri.h @@ -0,0 +1,11 @@ +/* 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)
+#endif /* __ASM_CHERI_H */ diff --git a/arch/arm64/kernel/morello.c b/arch/arm64/kernel/morello.c index ccbf26e77919..0bb7b3dbedec 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> @@ -21,10 +20,6 @@ #include <asm/morello.h> #include <asm/ptrace.h> -#ifdef CONFIG_CHERI_PURECAP_UABI -#include <cheriintrin.h> -#endif
- /* Private functions implemented in morello.S */ void __morello_cap_lo_hi_tag(uintcap_t cap, u64 *lo_val, u64 *hi_val, u8 *tag);
@@ -295,8 +290,8 @@ static void __init check_root_cap(uintcap_t cap) __morello_cap_lo_hi_tag(cap, &lo_val, &hi_val, &tag); /*
* Check that DDC has the reset value, otherwise morello_root_cap and
* all capabilities derived from it (especially those exposed to
* Check that DDC has the reset value, otherwise root capabilities and
* all capabilities derived from them (notably those exposed to
*/ if (!(tag == 1 &&
- userspace) may not be reliable.
@@ -307,17 +302,52 @@ 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, user_root_all_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 |
ARM_CAP_PERMISSION_BRANCH_SEALED_PAIR |
CHERI_PERM_SEAL | CHERI_PERM_UNSEAL |
ARM_CAP_PERMISSION_COMPARTMENT_ID);
- user_root_all_cap = ctemp;
- cheri_user_root_all_cap = user_root_all_cap;
Nit: This local variable user_root_all_cap seems to be extra. cheri_user_root_all_cap can be used to derive capabilities.
- ctemp = user_root_all_cap;
- ctemp = cheri_perms_and(ctemp, CHERI_PERMS_ROOTCAP | CHERI_PERMS_READ |
CHERI_PERMS_WRITE | CHERI_PERMS_EXEC |
ARM_CAP_PERMISSION_BRANCH_SEALED_PAIR);
- cheri_user_root_cap = ctemp;
- ctemp = user_root_all_cap;
- /*
* All object types, not a final decision - some of them may be later
* reserved to the kernel.
*/
- ctemp = cheri_bounds_set(ctemp, 1u << 15);
Nit: May a macro like MAX_OBJECT_TYPE for (1u << 15) will make it clear. Although a description for it is there.
- ctemp = cheri_perms_and(ctemp, CHERI_PERM_GLOBAL |
CHERI_PERM_SEAL | CHERI_PERM_UNSEAL);
- cheri_user_root_seal_cap = ctemp;
- morello_root_cap = (uintcap_t)cheri_ddc_get();
- /* Maximum userspace bounds for the time being. */
- ctemp = user_root_all_cap;
- ctemp = cheri_perms_and(ctemp, CHERI_PERM_GLOBAL |
ARM_CAP_PERMISSION_COMPARTMENT_ID);
- cheri_user_root_cid_cap = 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;