in drivers/virt/nitro_enclaves/ne_misc_dev.c [832:880]
static int ne_sanity_check_user_mem_region(struct ne_enclave *ne_enclave,
struct ne_user_memory_region mem_region)
{
struct ne_mem_region *ne_mem_region = NULL;
if (ne_enclave->mm != current->mm)
return -EIO;
if (mem_region.memory_size & (NE_MIN_MEM_REGION_SIZE - 1)) {
dev_err_ratelimited(ne_misc_dev.this_device,
"User space memory size is not multiple of 2 MiB\n");
return -NE_ERR_INVALID_MEM_REGION_SIZE;
}
if (!IS_ALIGNED(mem_region.userspace_addr, NE_MIN_MEM_REGION_SIZE)) {
dev_err_ratelimited(ne_misc_dev.this_device,
"User space address is not 2 MiB aligned\n");
return -NE_ERR_UNALIGNED_MEM_REGION_ADDR;
}
if ((mem_region.userspace_addr & (NE_MIN_MEM_REGION_SIZE - 1)) ||
!user_access_ok((void __user *)(unsigned long)mem_region.userspace_addr,
mem_region.memory_size)) {
dev_err_ratelimited(ne_misc_dev.this_device,
"Invalid user space address range\n");
return -NE_ERR_INVALID_MEM_REGION_ADDR;
}
list_for_each_entry(ne_mem_region, &ne_enclave->mem_regions_list,
mem_region_list_entry) {
u64 memory_size = ne_mem_region->memory_size;
u64 userspace_addr = ne_mem_region->userspace_addr;
if ((userspace_addr <= mem_region.userspace_addr &&
mem_region.userspace_addr < (userspace_addr + memory_size)) ||
(mem_region.userspace_addr <= userspace_addr &&
(mem_region.userspace_addr + mem_region.memory_size) > userspace_addr)) {
dev_err_ratelimited(ne_misc_dev.this_device,
"User space memory region already used\n");
return -NE_ERR_MEM_REGION_ALREADY_USED;
}
}
return 0;
}