From 44ca02a46b6fa0a8f1181fdc08efa779c3bdce80 Mon Sep 17 00:00:00 2001 From: Joan Lledó Date: Sat, 6 Nov 2021 09:13:32 +0100 Subject: vm: vm_region_get_proxy To get a proxy to the region a given address belongs to, with protection and range limited to the region ones. * include/mach/mach4.defs: vm_region_get_proxy RPC declaration * vm/vm_map.c: vm_region_get_proxy implementation Message-Id: <20211106081333.10366-2-jlledom@mailfence.com> --- vm/vm_map.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) (limited to 'vm/vm_map.c') diff --git a/vm/vm_map.c b/vm/vm_map.c index a687d365..900862d9 100644 --- a/vm/vm_map.c +++ b/vm/vm_map.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -53,6 +54,7 @@ #include #include #include +#include #include #include @@ -4806,6 +4808,60 @@ kern_return_t vm_region( return(KERN_SUCCESS); } +/* + * vm_region_get_proxy: + * + * Gets a proxy to the region that ADDRESS belongs to, starting at the + * region start, with MAX_PROTECTION and LEN limited by the region ones, + * and returns it in *PORT. + */ +kern_return_t +vm_region_get_proxy (task_t task, vm_address_t address, + vm_prot_t max_protection, vm_size_t len, + ipc_port_t *port) +{ + kern_return_t ret; + vm_map_entry_t entry, tmp_entry; + vm_offset_t offset, start; + ipc_port_t pager; + + if (task == TASK_NULL) + return(KERN_INVALID_ARGUMENT); + + vm_map_lock_read(task->map); + if (!vm_map_lookup_entry(task->map, address, &tmp_entry)) { + if ((entry = tmp_entry->vme_next) == vm_map_to_entry(task->map)) { + vm_map_unlock_read(task->map); + return(KERN_NO_SPACE); + } + } else { + entry = tmp_entry; + } + + /* Limit the allowed protection and range to the entry ones */ + if (len > entry->vme_end - entry->vme_start) { + vm_map_unlock_read(task->map); + return(KERN_INVALID_ARGUMENT); + } + + max_protection &= entry->max_protection; + pager = ipc_port_copy_send(entry->object.vm_object->pager); + offset = entry->offset; + start = 0; + + vm_map_unlock_read(task->map); + + ret = memory_object_create_proxy(task->itk_space, max_protection, + &pager, 1, + &offset, 1, + &start, 1, + &len, 1, port); + if (ret) + ipc_port_release_send(pager); + + return ret; +} + /* * Routine: vm_map_simplify * -- cgit v1.2.3