From: Amit Daniel Kachhap amitdaniel.kachhap@arm.com
Save the capability corresponding to the vDSO reservation in mm_context_t so that we can directly use it in ARCH_DLINFO, restricting the bounds and permissions of AT_SYSINFO_EHDR. We explicitly remove the VMem permission as per the PCuABI specification (we do not provide an owning capability for the vDSO).
Signed-off-by: Amit Daniel Kachhap amitdaniel.kachhap@arm.com Co-developed-by: Kevin Brodsky kevin.brodsky@arm.com Signed-off-by: Kevin Brodsky kevin.brodsky@arm.com --- arch/arm64/include/asm/elf.h | 9 ++------- arch/arm64/include/asm/mmu.h | 2 +- arch/arm64/kernel/vdso.c | 20 +++++++++++++++++--- 3 files changed, 20 insertions(+), 11 deletions(-)
diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h index 7d253fc3961c..be91c27ba24b 100644 --- a/arch/arm64/include/asm/elf.h +++ b/arch/arm64/include/asm/elf.h @@ -174,12 +174,7 @@ extern int aarch64_setup_additional_pages(struct linux_binprm *bprm, extern int purecap_setup_additional_pages(struct linux_binprm *bprm, int uses_interp); #define arch_setup_additional_pages purecap_setup_additional_pages -/* - * TODO [PCuABI]: Look into restricting the bounds of this capability to just - * the vDSO pages, as currently the bounds are of the root user capability. - */ -#define ARCH_DLINFO SETUP_DLINFO(uaddr_to_user_ptr_safe( \ - (elf_addr_t)current->mm->context.vdso)) +#define ARCH_DLINFO SETUP_DLINFO(current->mm->context.vdso) #else /* !CONFIG_CHERI_PURECAP_UABI */ #define arch_setup_additional_pages aarch64_setup_additional_pages #define ARCH_DLINFO SETUP_DLINFO((elf_addr_t)current->mm->context.vdso) @@ -219,7 +214,7 @@ typedef compat_elf_greg_t compat_elf_gregset_t[COMPAT_ELF_NGREG]; SET_PERSONALITY_AARCH64(); \ })
-#define COMPAT_ARCH_DLINFO SETUP_DLINFO((elf_addr_t)current->mm->context.vdso) +#define COMPAT_ARCH_DLINFO SETUP_DLINFO(current->mm->context.vdso)
#define compat_arch_setup_additional_pages aarch64_setup_additional_pages
diff --git a/arch/arm64/include/asm/mmu.h b/arch/arm64/include/asm/mmu.h index 12a7889f0a37..5b3e3e8c0fe1 100644 --- a/arch/arm64/include/asm/mmu.h +++ b/arch/arm64/include/asm/mmu.h @@ -23,7 +23,7 @@ typedef struct { void *sigpage; #endif refcount_t pinned; - void *vdso; + user_uintptr_t vdso; unsigned long flags; } mm_context_t;
diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c index f9059577581f..9cda023bda85 100644 --- a/arch/arm64/kernel/vdso.c +++ b/arch/arm64/kernel/vdso.c @@ -84,10 +84,23 @@ static union { } vdso_data_store __page_aligned_data; struct vdso_data *vdso_data = vdso_data_store.data;
+static user_uintptr_t make_vdso_ptr(struct vm_area_struct *vdso_text_vma) +{ + user_uintptr_t ret; + + ret = reserv_vma_make_user_ptr_owning(vdso_text_vma); +#ifdef CONFIG_CHERI_PURECAP_UABI + if (!is_compat_task()) + ret = cheri_perms_clear(ret, CHERI_PERM_SW_VMEM); +#endif + + return ret; +} + static int vdso_mremap(const struct vm_special_mapping *sm, struct vm_area_struct *new_vma) { - current->mm->context.vdso = (void *)new_vma->vm_start; + current->mm->context.vdso = make_vdso_ptr(new_vma);
return 0; } @@ -233,7 +246,6 @@ static int __setup_additional_pages(enum vdso_abi abi, gp_flags = VM_ARM64_BTI;
vdso_text_base = vdso_base + VVAR_NR_PAGES * PAGE_SIZE; - mm->context.vdso = (void *)vdso_text_base; ret = _install_special_mapping(mm, vdso_text_base, vdso_text_len, VM_READ|VM_EXEC|gp_flags| VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC, @@ -245,10 +257,12 @@ static int __setup_additional_pages(enum vdso_abi abi, PROT_READ | PROT_EXEC)) goto up_fail;
+ mm->context.vdso = make_vdso_ptr(ret); + return 0;
up_fail: - mm->context.vdso = NULL; + mm->context.vdso = 0; return PTR_ERR(ret); }