summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoan Lledó <jlledom@member.fsf.org>2021-08-09 19:27:52 +0200
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2021-08-09 19:28:31 +0200
commitb12549f5cb0495085a39908bfe9c9c4d1b068cca (patch)
tree46a5e07562a866b4ad7936ef2fe2b5eddfcfe62d
parent5f709eace1fb688ed6dcfa7626c113791ed86dc6 (diff)
Memory object proxy: add support for ranges and nesting
-rw-r--r--vm/memory_object_proxy.c26
-rw-r--r--vm/memory_object_proxy.h4
-rw-r--r--vm/vm_user.c27
3 files changed, 38 insertions, 19 deletions
diff --git a/vm/memory_object_proxy.c b/vm/memory_object_proxy.c
index 012369a0..160a1b30 100644
--- a/vm/memory_object_proxy.c
+++ b/vm/memory_object_proxy.c
@@ -56,6 +56,8 @@ struct memory_object_proxy
ipc_port_t object;
vm_prot_t max_protection;
+ vm_offset_t start;
+ vm_offset_t len;
};
typedef struct memory_object_proxy *memory_object_proxy_t;
@@ -66,7 +68,7 @@ memory_object_proxy_init (void)
kmem_cache_init (&memory_object_proxy_cache, "memory_object_proxy",
sizeof (struct memory_object_proxy), 0, NULL, 0);
}
-
+
/* Lookup a proxy memory object by its port. */
static memory_object_proxy_t
memory_object_proxy_port_lookup (ipc_port_t port)
@@ -149,10 +151,6 @@ memory_object_create_proxy (const ipc_space_t space, vm_prot_t max_protection,
if (offset[0] != 0)
return KERN_INVALID_ARGUMENT;
- /* FIXME: Support a different range from total. */
- if (start[0] != 0 || len[0] != (vm_offset_t) ~0)
- return KERN_INVALID_ARGUMENT;
-
proxy = (memory_object_proxy_t) kmem_cache_alloc (&memory_object_proxy_cache);
/* Allocate port, keeping a reference for it. */
@@ -173,12 +171,13 @@ memory_object_create_proxy (const ipc_space_t space, vm_prot_t max_protection,
proxy->object = ipc_port_copy_send (object[0]);
proxy->max_protection = max_protection;
+ proxy->start = start[0];
+ proxy->len = len[0];
*port = ipc_port_make_send (proxy->port);
return KERN_SUCCESS;
}
-
/* Lookup the real memory object and maximum protection for the proxy
memory object port PORT, for which the caller holds a reference.
*OBJECT is only guaranteed to be valid as long as the caller holds
@@ -187,7 +186,8 @@ memory_object_create_proxy (const ipc_space_t space, vm_prot_t max_protection,
KERN_INVALID_ARGUMENT. */
kern_return_t
memory_object_proxy_lookup (ipc_port_t port, ipc_port_t *object,
- vm_prot_t *max_protection)
+ vm_prot_t *max_protection, vm_offset_t *start,
+ vm_offset_t *len)
{
memory_object_proxy_t proxy;
@@ -195,8 +195,16 @@ memory_object_proxy_lookup (ipc_port_t port, ipc_port_t *object,
if (!proxy)
return KERN_INVALID_ARGUMENT;
- *object = proxy->object;
- *max_protection = proxy->max_protection;
+ *max_protection = proxy->max_protection;
+ *start = 0;
+ *len = proxy->len;
+
+ do
+ {
+ *object = proxy->object;
+ *start += proxy->start;
+ }
+ while ((proxy = memory_object_proxy_port_lookup (proxy->object)));
return KERN_SUCCESS;
}
diff --git a/vm/memory_object_proxy.h b/vm/memory_object_proxy.h
index dc0ea747..8b3f2025 100644
--- a/vm/memory_object_proxy.h
+++ b/vm/memory_object_proxy.h
@@ -32,6 +32,8 @@ extern void memory_object_proxy_init (void);
extern boolean_t memory_object_proxy_notify (mach_msg_header_t *msg);
extern kern_return_t memory_object_proxy_lookup (ipc_port_t port,
ipc_port_t *object,
- vm_prot_t *max_protection);
+ vm_prot_t *max_protection,
+ vm_offset_t *start,
+ vm_offset_t *len);
#endif /* _VM_MEMORY_OBJECT_PROXY_H_ */
diff --git a/vm/vm_user.c b/vm/vm_user.c
index 42ee5e08..8da8dea1 100644
--- a/vm/vm_user.c
+++ b/vm/vm_user.c
@@ -1,32 +1,32 @@
-/*
+/*
* Mach Operating System
* Copyright (c) 1991,1990,1989,1988 Carnegie Mellon University
* All Rights Reserved.
- *
+ *
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
- *
+ *
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
+ *
* Carnegie Mellon requests users of this software to return to
- *
+ *
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
- *
+ *
* any improvements or extensions that they make and grant Carnegie Mellon
* the rights to redistribute these changes.
*/
/*
* File: vm/vm_user.c
* Author: Avadis Tevanian, Jr., Michael Wayne Young
- *
+ *
* User-exported virtual memory functions.
*/
@@ -158,7 +158,7 @@ kern_return_t vm_protect(
boolean_t set_maximum,
vm_prot_t new_protection)
{
- if ((map == VM_MAP_NULL) ||
+ if ((map == VM_MAP_NULL) ||
(new_protection & ~(VM_PROT_ALL|VM_PROT_NOTIFY)))
return(KERN_INVALID_ARGUMENT);
@@ -350,8 +350,11 @@ kern_return_t vm_map(
{
ipc_port_t real_memobj;
vm_prot_t prot;
+ vm_offset_t start;
+ vm_offset_t len;
+
result = memory_object_proxy_lookup (memory_object, &real_memobj,
- &prot);
+ &prot, &start, &len);
if (result != KERN_SUCCESS)
return result;
@@ -368,6 +371,12 @@ kern_return_t vm_map(
return KERN_PROTECTION_FAILURE;
}
+ /* Reduce the allowed range */
+ if ((start + offset + size) > (start + len))
+ return KERN_INVALID_ARGUMENT;
+
+ offset += start;
+
if ((object = vm_object_enter(real_memobj, size, FALSE))
== VM_OBJECT_NULL)
return KERN_INVALID_ARGUMENT;