As a privileged operation (disabled by default), arbitrary capabilities may be created in a process via ptrace. Now that we have defined generic user root capabilities, make use of cheri_user_root_all_cap (the "root of roots") to build these capabilities from, instead of the kernel root capability. Change the name of the helper accordingly and clarify that it should not be used for unprivileged operations.
Using cheri_user_root_all_cap is a clear improvement, however this still allows creating capabilities that could not otherwise be obtained in PCuABI (e.g. with Seal combined with other permissions). Considering the additional complexity that restricting this further would entail, and the operation being only involved in privileged debugging, this situation is considered acceptable.
Signed-off-by: Kevin Brodsky kevin.brodsky@arm.com --- arch/arm64/include/asm/morello.h | 10 +++++++++- arch/arm64/kernel/morello.c | 4 ++-- arch/arm64/kernel/ptrace.c | 2 +- arch/arm64/lib/morello.S | 9 +++------ 4 files changed, 15 insertions(+), 10 deletions(-)
diff --git a/arch/arm64/include/asm/morello.h b/arch/arm64/include/asm/morello.h index e60ad5727fca..40a51fbe06d6 100644 --- a/arch/arm64/include/asm/morello.h +++ b/arch/arm64/include/asm/morello.h @@ -28,7 +28,15 @@ struct morello_state { };
void morello_cap_get_val_tag(uintcap_t cap, __uint128_t *val, u8 *tag); -uintcap_t morello_build_cap_from_root_cap(const __uint128_t *val, u8 tag); + +/* + * Builds a user capability from a 128-bit pattern + tag. The capability will + * be derived from cheri_user_root_all_cap and the object type will be + * preserved. + * + * This function should only be used for privileged operations (e.g. debug). + */ +uintcap_t morello_build_any_user_cap(const __uint128_t *val, u8 tag);
uintcap_t morello_get_root_cap(void);
diff --git a/arch/arm64/kernel/morello.c b/arch/arm64/kernel/morello.c index 9dc42231df20..ab83eb407eb9 100644 --- a/arch/arm64/kernel/morello.c +++ b/arch/arm64/kernel/morello.c @@ -203,8 +203,8 @@ static int access_remote_cap(struct task_struct *tsk, struct mm_struct *mm, goto out_put; }
- *kaddr = morello_build_cap_from_root_cap(&user_cap->val, - user_cap->tag); + *kaddr = morello_build_any_user_cap(&user_cap->val, + user_cap->tag); flush_ptrace_access(vma, (unsigned long)kaddr, (unsigned long)kaddr + sizeof(uintcap_t)); set_page_dirty_lock(page); diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c index db29bbe5ceae..6e3f6dc9c6f5 100644 --- a/arch/arm64/kernel/ptrace.c +++ b/arch/arm64/kernel/ptrace.c @@ -1167,7 +1167,7 @@ static int morello_get(struct task_struct *target,
#define MORELLO_STATE_BUILD_CAP(state, reg, cap) do { \ u8 tag = (state.tag_map >> MORELLO_PT_TAG_MAP_REG_BIT(reg)) & 0x1; \ - cap = morello_build_cap_from_root_cap(&state.reg, tag); \ + cap = morello_build_any_user_cap(&state.reg, tag); \ } while (0)
static int morello_set(struct task_struct *target, diff --git a/arch/arm64/lib/morello.S b/arch/arm64/lib/morello.S index e1cd14355721..62e8a6235134 100644 --- a/arch/arm64/lib/morello.S +++ b/arch/arm64/lib/morello.S @@ -22,7 +22,7 @@ SYM_FUNC_START(morello_cap_get_val_tag) ret SYM_FUNC_END(morello_cap_get_val_tag)
-SYM_FUNC_START(morello_build_cap_from_root_cap) +SYM_FUNC_START(morello_build_any_user_cap) ldr c0, [x0] cbz w1, 1f /* @@ -31,11 +31,8 @@ SYM_FUNC_START(morello_build_cap_from_root_cap) * In case c0 is sealed (non-zero object type), we need to extract the * object type first to be able to reseal it after BUILD. The CSEAL * instruction is used to cover the case where c0 was not sealed. - * - * TODO [PCuABI] - the user root capability should be used, not the - * kernel one. */ - adr_l x3, morello_root_cap + adr_l x3, cheri_user_root_all_cap ldr c3, [x3]
cpytype c4, c3, c0 @@ -47,7 +44,7 @@ SYM_FUNC_START(morello_build_cap_from_root_cap) clrtag c0, c0 2: ret -SYM_FUNC_END(morello_build_cap_from_root_cap) +SYM_FUNC_END(morello_build_any_user_cap)
SYM_FUNC_START(morello_capcpy) mov x3, x0