diff --git a/vm/memory_object_proxy.c b/vm/memory_object_proxy.c index 01bce2a5..912387f0 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) @@ -143,10 +145,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. */ @@ -167,6 +165,8 @@ 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; @@ -181,7 +181,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; @@ -191,6 +192,8 @@ memory_object_proxy_lookup (ipc_port_t port, ipc_port_t *object, *object = proxy->object; *max_protection = proxy->max_protection; + *start = proxy->start; + *len = proxy->len; 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 4d5728c8..6e82cc60 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,9 +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) /* Really no luck */ return result; @@ -361,6 +363,12 @@ kern_return_t vm_map( max_protection &= prot; cur_protection &= prot; + /* 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;