Use the recently introduced PCuABI reservation interfaces to verify the address range for mincore syscall.
Signed-off-by: Amit Daniel Kachhap amit.kachhap@arm.com --- mm/mincore.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/mm/mincore.c b/mm/mincore.c index 3a307bfa91c4..70dc9af2cfb7 100644 --- a/mm/mincore.c +++ b/mm/mincore.c @@ -18,6 +18,7 @@ #include <linux/shmem_fs.h> #include <linux/hugetlb.h> #include <linux/pgtable.h> +#include <linux/cap_addr_mgmt.h>
#include <linux/uaccess.h> #include "swap.h" @@ -229,14 +230,19 @@ static long do_mincore(unsigned long addr, unsigned long pages, unsigned char *v * mapped * -EAGAIN - A kernel resource was temporarily unavailable. */ -SYSCALL_DEFINE3(mincore, unsigned long, start, size_t, len, +SYSCALL_DEFINE3(mincore, user_uintptr_t, user_start, size_t, len, unsigned char __user *, vec) { long retval; unsigned long pages; unsigned char *tmp; + unsigned long start = untagged_addr((ptraddr_t)user_start);
- start = untagged_addr(start); +#ifdef CONFIG_CHERI_PURECAP_UABI + user_start = cheri_address_set(user_start, start); + if (!capability_owns_range(user_start, start, len)) + return -EINVAL; +#endif
/* Check the start address: needs to be page-aligned.. */ if (start & ~PAGE_MASK) @@ -253,6 +259,14 @@ SYSCALL_DEFINE3(mincore, unsigned long, start, size_t, len, if (!access_ok(vec, pages)) return -EFAULT;
+#ifdef CONFIG_CHERI_PURECAP_UABI + mmap_read_lock(current->mm); + /* Check if the range exists within the reservation with mmap lock. */ + retval = reserv_mt_capability_bound_valid(¤t->mm->reserv_mt, user_start); + mmap_read_unlock(current->mm); + if (!retval) + return -ERESERVATION; +#endif tmp = (void *) __get_free_page(GFP_USER); if (!tmp) return -EAGAIN;