xref: /xnu-11417.140.69/osfmk/vm/vm32_user.c (revision 43a90889846e00bfb5cf1d255cdc0a701a1e05a4) !
1 /*
2  * Copyright (c) 2008-2016 Apple Inc. All rights reserved.
3  *
4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5  *
6  * This file contains Original Code and/or Modifications of Original Code
7  * as defined in and that are subject to the Apple Public Source License
8  * Version 2.0 (the 'License'). You may not use this file except in
9  * compliance with the License. The rights granted to you under the License
10  * may not be used to create, or enable the creation or redistribution of,
11  * unlawful or unlicensed copies of an Apple operating system, or to
12  * circumvent, violate, or enable the circumvention or violation of, any
13  * terms of an Apple operating system software license agreement.
14  *
15  * Please obtain a copy of the License at
16  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17  *
18  * The Original Code and all software distributed under the License are
19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23  * Please see the License for the specific language governing rights and
24  * limitations under the License.
25  *
26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27  */
28 /*
29  * @OSF_COPYRIGHT@
30  */
31 /*
32  * Mach Operating System
33  * Copyright (c) 1991,1990,1989,1988 Carnegie Mellon University
34  * All Rights Reserved.
35  *
36  * Permission to use, copy, modify and distribute this software and its
37  * documentation is hereby granted, provided that both the copyright
38  * notice and this permission notice appear in all copies of the
39  * software, derivative works or modified versions, and any portions
40  * thereof, and that both notices appear in supporting documentation.
41  *
42  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
43  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
44  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
45  *
46  * Carnegie Mellon requests users of this software to return to
47  *
48  *  Software Distribution Coordinator  or  [email protected]
49  *  School of Computer Science
50  *  Carnegie Mellon University
51  *  Pittsburgh PA 15213-3890
52  *
53  * any improvements or extensions that they make and grant Carnegie Mellon
54  * the rights to redistribute these changes.
55  */
56 /*
57  */
58 /*
59  *	File:	vm/vm32_user.c
60  *	Author:	Avadis Tevanian, Jr., Michael Wayne Young
61  *
62  *	User-exported virtual memory functions.
63  */
64 
65 #include <debug.h>
66 
67 #include <mach/boolean.h>
68 #include <mach/kern_return.h>
69 #include <mach/mach_types.h>    /* to get vm_address_t */
70 #include <mach/memory_object.h>
71 #include <mach/std_types.h>     /* to get pointer_t */
72 #include <mach/vm_attributes.h>
73 #include <mach/vm_param.h>
74 #include <mach/vm_statistics.h>
75 #include <mach/mach_syscalls.h>
76 
77 #include <mach/host_priv_server.h>
78 #include <mach/mach_vm_server.h>
79 #include <mach/vm32_map_server.h>
80 
81 #include <kern/host.h>
82 #include <kern/task.h>
83 #include <kern/misc_protos.h>
84 #include <vm/vm_fault.h>
85 #include <vm/vm_map_internal.h>
86 #include <vm/vm_object_xnu.h>
87 #include <vm/vm_page.h>
88 #include <vm/memory_object.h>
89 #include <vm/vm_pageout.h>
90 #include <vm/vm_protos.h>
91 #include <vm/vm_iokit.h>
92 #include <vm/vm_sanitize_internal.h>
93 #include <vm/vm_map_internal.h>
94 
95 #ifdef VM32_SUPPORT
96 
97 /*
98  * See vm_user.c for the real implementation of all of these functions.
99  * We call through to the mach_ "wide" versions of the routines, and trust
100  * that the VM system verifies the arguments and only returns address that
101  * are appropriate for the task's address space size.
102  *
103  * New VM call implementations should not be added here, because they would
104  * be available only to 32-bit userspace clients. Add them to vm_user.c
105  * and the corresponding prototype to mach_vm.defs (subsystem 4800).
106  */
107 
108 kern_return_t
vm32_vm_allocate(vm_map_t map,vm32_address_ut * addr32,vm32_size_ut size32,int flags)109 vm32_vm_allocate(
110 	vm_map_t                map,
111 	vm32_address_ut        *addr32,
112 	vm32_size_ut            size32,
113 	int                     flags)
114 {
115 	mach_vm_address_ut      addr;
116 	mach_vm_size_ut         size;
117 	kern_return_t           kr;
118 
119 	addr    = vm_sanitize_expand_addr_to_64(*addr32);
120 	size    = vm_sanitize_expand_size_to_64(size32);
121 	kr      = mach_vm_allocate_external(map, &addr, size, flags);
122 	*addr32 = vm_sanitize_trunc_addr_to_32(addr);
123 
124 	return kr;
125 }
126 
127 kern_return_t
vm32_vm_deallocate(vm_map_t map,vm32_offset_ut start32,vm32_size_ut size32)128 vm32_vm_deallocate(
129 	vm_map_t                map,
130 	vm32_offset_ut          start32,
131 	vm32_size_ut            size32)
132 {
133 	mach_vm_offset_ut start;
134 	mach_vm_size_ut   size;
135 	vm32_address_ut   discard;
136 
137 	if (vm_sanitize_add_overflow(start32, size32, &discard)) {
138 		return KERN_INVALID_ARGUMENT;
139 	}
140 
141 	start = vm_sanitize_expand_addr_to_64(start32);
142 	size = vm_sanitize_expand_size_to_64(size32);
143 
144 	return mach_vm_deallocate(map, start, size);
145 }
146 
147 kern_return_t
vm32_vm_inherit(vm_map_t map,vm32_offset_ut start32,vm32_size_ut size32,vm_inherit_ut new_inheritance)148 vm32_vm_inherit(
149 	vm_map_t                map,
150 	vm32_offset_ut          start32,
151 	vm32_size_ut            size32,
152 	vm_inherit_ut           new_inheritance)
153 {
154 	mach_vm_offset_ut start;
155 	mach_vm_size_ut   size;
156 	vm32_address_ut   discard;
157 
158 	if (map == VM_MAP_NULL ||
159 	    vm_sanitize_add_overflow(start32, size32, &discard)) {
160 		return KERN_INVALID_ARGUMENT;
161 	}
162 
163 	start = vm_sanitize_expand_addr_to_64(start32);
164 	size = vm_sanitize_expand_size_to_64(size32);
165 
166 	return mach_vm_inherit(map,
167 	           start,
168 	           size,
169 	           new_inheritance);
170 }
171 
172 kern_return_t
vm32_vm_protect(vm_map_t map,vm32_offset_ut start32,vm32_size_ut size32,boolean_t set_maximum,vm_prot_ut new_protection)173 vm32_vm_protect(
174 	vm_map_t                map,
175 	vm32_offset_ut          start32,
176 	vm32_size_ut            size32,
177 	boolean_t               set_maximum,
178 	vm_prot_ut              new_protection)
179 {
180 	mach_vm_offset_ut start;
181 	mach_vm_size_ut   size;
182 	vm32_address_ut   discard;
183 
184 	if (map == VM_MAP_NULL ||
185 	    vm_sanitize_add_overflow(start32, size32, &discard)) {
186 		return KERN_INVALID_ARGUMENT;
187 	}
188 
189 	start = vm_sanitize_expand_addr_to_64(start32);
190 	size = vm_sanitize_expand_size_to_64(size32);
191 
192 	return mach_vm_protect(map, start,
193 	           size,
194 	           set_maximum,
195 	           new_protection);
196 }
197 
198 kern_return_t
vm32_vm_machine_attribute(vm_map_t map,vm32_address_ut addr32,vm32_size_ut size32,vm_machine_attribute_t attribute,vm_machine_attribute_val_t * value)199 vm32_vm_machine_attribute(
200 	vm_map_t                map,
201 	vm32_address_ut         addr32,
202 	vm32_size_ut            size32,
203 	vm_machine_attribute_t  attribute,
204 	vm_machine_attribute_val_t *value) /* IN/OUT */
205 {
206 	mach_vm_offset_ut addr;
207 	mach_vm_size_ut   size;
208 	vm32_address_ut   discard;
209 
210 	if (map == VM_MAP_NULL ||
211 	    vm_sanitize_add_overflow(addr32, size32, &discard)) {
212 		return KERN_INVALID_ARGUMENT;
213 	}
214 
215 	addr = vm_sanitize_expand_addr_to_64(addr32);
216 	size = vm_sanitize_expand_size_to_64(size32);
217 
218 	return mach_vm_machine_attribute(map, addr, size, attribute, value);
219 }
220 
221 kern_return_t
vm32_vm_read(vm_map_t map,vm32_address_ut addr32,vm32_size_ut size32,pointer_ut * data,mach_msg_type_number_t * data_size)222 vm32_vm_read(
223 	vm_map_t                map,
224 	vm32_address_ut         addr32,
225 	vm32_size_ut            size32,
226 	pointer_ut             *data,
227 	mach_msg_type_number_t *data_size)
228 {
229 	mach_vm_offset_ut addr;
230 	mach_vm_size_ut   size;
231 
232 	addr = vm_sanitize_expand_addr_to_64(addr32);
233 	size = vm_sanitize_expand_size_to_64(size32);
234 
235 	return mach_vm_read(map, addr, size, data, data_size);
236 }
237 
238 kern_return_t
vm32_vm_read_list(vm_map_t map,vm32_read_entry_t data_list,natural_t count)239 vm32_vm_read_list(
240 	vm_map_t                map,
241 	vm32_read_entry_t       data_list,
242 	natural_t               count)
243 {
244 	mach_vm_read_entry_t    mdata_list;
245 	mach_msg_type_number_t  i;
246 	kern_return_t                   result;
247 
248 	for (i = 0; i < VM_MAP_ENTRY_MAX; i++) {
249 		mdata_list[i].address = data_list[i].address;
250 		mdata_list[i].size = data_list[i].size;
251 	}
252 
253 	result = mach_vm_read_list(map, mdata_list, count);
254 
255 	for (i = 0; i < VM_MAP_ENTRY_MAX; i++) {
256 		data_list[i].address = CAST_DOWN_EXPLICIT(vm32_address_t, mdata_list[i].address);
257 		data_list[i].size = CAST_DOWN_EXPLICIT(vm32_size_t, mdata_list[i].size);
258 	}
259 
260 	return result;
261 }
262 
263 kern_return_t
vm32_vm_read_overwrite(vm_map_t map,vm32_address_ut addr32,vm32_size_ut size32,vm32_address_ut data32,vm32_size_ut * data_size32)264 vm32_vm_read_overwrite(
265 	vm_map_t                map,
266 	vm32_address_ut         addr32,
267 	vm32_size_ut            size32,
268 	vm32_address_ut         data32,
269 	vm32_size_ut           *data_size32)
270 {
271 	mach_vm_offset_ut addr, data;
272 	mach_vm_size_ut   size, data_size;
273 	kern_return_t     result;
274 
275 	addr = vm_sanitize_expand_addr_to_64(addr32);
276 	size = vm_sanitize_expand_size_to_64(size32);
277 	data = vm_sanitize_expand_addr_to_64(data32);
278 	data_size = vm_sanitize_expand_size_to_64(*data_size32);
279 
280 	result = mach_vm_read_overwrite(map, addr, size, data, &data_size);
281 	*data_size32 = vm_sanitize_trunc_size_to_32(data_size);
282 
283 	return result;
284 }
285 
286 kern_return_t
vm32_vm_write(vm_map_t map,vm32_address_ut addr32,pointer_ut data,mach_msg_type_number_t size)287 vm32_vm_write(
288 	vm_map_t                map,
289 	vm32_address_ut         addr32,
290 	pointer_ut              data,
291 	mach_msg_type_number_t  size)
292 {
293 	mach_vm_offset_ut addr;
294 
295 	addr = vm_sanitize_expand_addr_to_64(addr32);
296 	return mach_vm_write(map, addr, data, size);
297 }
298 
299 kern_return_t
vm32_vm_copy(vm_map_t map,vm32_address_ut src_addr32,vm32_size_ut size32,vm32_address_ut dst_addr32)300 vm32_vm_copy(
301 	vm_map_t                map,
302 	vm32_address_ut         src_addr32,
303 	vm32_size_ut            size32,
304 	vm32_address_ut         dst_addr32)
305 {
306 	mach_vm_offset_ut src_addr, dst_addr;
307 	mach_vm_size_ut   size;
308 
309 	src_addr = vm_sanitize_expand_addr_to_64(src_addr32);
310 	size     = vm_sanitize_expand_size_to_64(size32);
311 	dst_addr = vm_sanitize_expand_addr_to_64(dst_addr32);
312 
313 	return mach_vm_copy(map, src_addr, size, dst_addr);
314 }
315 
316 kern_return_t
vm32_vm_map_64(vm_map_t target_map,vm32_offset_ut * addr32,vm32_size_ut size32,vm32_offset_ut mask32,int flags,ipc_port_t port,memory_object_offset_ut offset,boolean_t copy,vm_prot_ut cur_protection,vm_prot_ut max_protection,vm_inherit_ut inheritance)317 vm32_vm_map_64(
318 	vm_map_t                target_map,
319 	vm32_offset_ut         *addr32,
320 	vm32_size_ut            size32,
321 	vm32_offset_ut          mask32,
322 	int                     flags,
323 	ipc_port_t              port,
324 	memory_object_offset_ut offset,
325 	boolean_t               copy,
326 	vm_prot_ut              cur_protection,
327 	vm_prot_ut              max_protection,
328 	vm_inherit_ut           inheritance)
329 {
330 	mach_vm_offset_ut addr, mask;
331 	mach_vm_size_ut   size;
332 	kern_return_t     result;
333 
334 	addr = vm_sanitize_expand_addr_to_64(*addr32);
335 	size = vm_sanitize_expand_size_to_64(size32);
336 	mask = vm_sanitize_expand_addr_to_64(mask32);
337 
338 	result  = mach_vm_map_external(target_map, &addr, size, mask,
339 	    flags, port, offset, copy,
340 	    cur_protection, max_protection, inheritance);
341 	*addr32 = vm_sanitize_trunc_addr_to_32(addr);
342 
343 	return result;
344 }
345 
346 kern_return_t
vm32_vm_map(vm_map_t target_map,vm32_offset_ut * address,vm32_size_ut size,vm32_offset_ut mask,int flags,ipc_port_t port,vm32_offset_ut offset32,boolean_t copy,vm_prot_ut cur_protection,vm_prot_ut max_protection,vm_inherit_ut inheritance)347 vm32_vm_map(
348 	vm_map_t                target_map,
349 	vm32_offset_ut         *address,
350 	vm32_size_ut            size,
351 	vm32_offset_ut          mask,
352 	int                     flags,
353 	ipc_port_t              port,
354 	vm32_offset_ut          offset32,
355 	boolean_t               copy,
356 	vm_prot_ut              cur_protection,
357 	vm_prot_ut              max_protection,
358 	vm_inherit_ut           inheritance)
359 {
360 	memory_object_offset_ut offset;
361 
362 	offset = vm_sanitize_expand_addr_to_64(offset32);
363 	return vm32_vm_map_64(target_map, address, size, mask,
364 	           flags, port, offset, copy,
365 	           cur_protection, max_protection, inheritance);
366 }
367 
368 kern_return_t
vm32_vm_remap(vm_map_t target_map,vm32_offset_ut * addr32,vm32_size_ut size32,vm32_offset_ut mask32,boolean_t anywhere,vm_map_t src_map,vm32_offset_ut src_addr32,boolean_t copy,vm_prot_ut * cur_protection,vm_prot_ut * max_protection,vm_inherit_ut inheritance)369 vm32_vm_remap(
370 	vm_map_t                target_map,
371 	vm32_offset_ut         *addr32,
372 	vm32_size_ut            size32,
373 	vm32_offset_ut          mask32,
374 	boolean_t               anywhere,
375 	vm_map_t                src_map,
376 	vm32_offset_ut          src_addr32,
377 	boolean_t               copy,
378 	vm_prot_ut             *cur_protection,
379 	vm_prot_ut             *max_protection,
380 	vm_inherit_ut           inheritance)
381 {
382 	mach_vm_offset_ut addr, mask, src_addr;
383 	mach_vm_size_ut   size;
384 	kern_return_t     result;
385 
386 	addr = vm_sanitize_expand_addr_to_64(*addr32);
387 	size = vm_sanitize_expand_size_to_64(size32);
388 	mask = vm_sanitize_expand_addr_to_64(mask32);
389 	src_addr = vm_sanitize_expand_addr_to_64(src_addr32);
390 
391 	result  = mach_vm_remap_external(target_map, &addr, size, mask,
392 	    anywhere, src_map, src_addr, copy,
393 	    cur_protection, max_protection, inheritance);
394 	*addr32 = vm_sanitize_trunc_addr_to_32(addr);
395 
396 
397 	return result;
398 }
399 
400 kern_return_t
vm32_vm_msync(vm_map_t map,vm32_address_ut addr32,vm32_size_ut size32,vm_sync_t sync_flags)401 vm32_vm_msync(
402 	vm_map_t                map,
403 	vm32_address_ut         addr32,
404 	vm32_size_ut            size32,
405 	vm_sync_t               sync_flags)
406 {
407 	mach_vm_offset_ut addr;
408 	mach_vm_size_ut   size;
409 
410 	addr = vm_sanitize_expand_addr_to_64(addr32);
411 	size = vm_sanitize_expand_size_to_64(size32);
412 	return mach_vm_msync(map, addr, size, sync_flags);
413 }
414 
415 kern_return_t
vm32_vm_behavior_set(vm_map_t map,vm32_offset_ut start32,vm32_size_ut size32,vm_behavior_ut new_behavior)416 vm32_vm_behavior_set(
417 	vm_map_t                map,
418 	vm32_offset_ut           start32,
419 	vm32_size_ut             size32,
420 	vm_behavior_ut           new_behavior)
421 {
422 	vm_address_ut     start;
423 	vm_size_ut        size;
424 	vm32_address_ut   discard;
425 
426 	if (vm_sanitize_add_overflow(start32, size32, &discard)) {
427 		return KERN_INVALID_ARGUMENT;
428 	}
429 
430 	start = vm_sanitize_expand_addr_to_64(start32);
431 	size = vm_sanitize_expand_size_to_64(size32);
432 
433 	return mach_vm_behavior_set(map, start, size, new_behavior);
434 }
435 
436 static inline kern_return_t
vm32_region_get_kern_return(kern_return_t kr,vm_offset_ut addr,vm_size_ut size)437 vm32_region_get_kern_return(
438 	kern_return_t           kr,
439 	vm_offset_ut            addr,
440 	vm_size_ut              size)
441 {
442 	vm_offset_ut end = vm_sanitize_compute_ut_end(addr, size);
443 
444 	if (KERN_SUCCESS == kr && VM_SANITIZE_UNSAFE_UNWRAP(end) > VM32_MAX_ADDRESS) {
445 		return KERN_INVALID_ADDRESS;
446 	}
447 	return kr;
448 }
449 
450 kern_return_t
vm32_vm_region_64(vm_map_t map,vm32_offset_ut * addr32,vm32_size_ut * size32,vm_region_flavor_t flavor,vm_region_info_t info,mach_msg_type_number_t * count,mach_port_t * object_name)451 vm32_vm_region_64(
452 	vm_map_t                map,
453 	vm32_offset_ut         *addr32,         /* IN/OUT */
454 	vm32_size_ut           *size32,         /* OUT */
455 	vm_region_flavor_t      flavor,         /* IN */
456 	vm_region_info_t        info,           /* OUT */
457 	mach_msg_type_number_t *count,          /* IN/OUT */
458 	mach_port_t            *object_name)    /* OUT */
459 {
460 	mach_vm_offset_ut addr;
461 	mach_vm_size_ut   size;
462 	kern_return_t     kr;
463 
464 	addr = vm_sanitize_expand_addr_to_64(*addr32);
465 	size = vm_sanitize_expand_size_to_64(*size32);
466 
467 	kr = mach_vm_region(map, &addr, &size, flavor, info, count, object_name);
468 
469 	*addr32 = vm_sanitize_trunc_addr_to_32(addr);
470 	*size32 = vm_sanitize_trunc_size_to_32(size);
471 
472 	return kr;
473 }
474 
475 kern_return_t
vm32_vm_region(vm_map_t map,vm32_address_ut * addr32,vm32_size_ut * size32,vm_region_flavor_t flavor,vm_region_info_t info,mach_msg_type_number_t * count,mach_port_t * object_name)476 vm32_vm_region(
477 	vm_map_t                map,
478 	vm32_address_ut        *addr32,         /* IN/OUT */
479 	vm32_size_ut           *size32,         /* OUT */
480 	vm_region_flavor_t      flavor,         /* IN */
481 	vm_region_info_t        info,           /* OUT */
482 	mach_msg_type_number_t *count,          /* IN/OUT */
483 	mach_port_t            *object_name)    /* OUT */
484 {
485 	mach_vm_offset_ut addr;
486 	mach_vm_size_ut   size;
487 	kern_return_t     kr;
488 
489 	if (VM_MAP_NULL == map) {
490 		return KERN_INVALID_ARGUMENT;
491 	}
492 
493 	addr = vm_sanitize_expand_addr_to_64(*addr32);
494 	size = vm_sanitize_expand_size_to_64(*size32);
495 
496 	kr = vm_map_region(map, &addr, &size, flavor, info, count, object_name);
497 
498 	*addr32 = vm_sanitize_trunc_addr_to_32(addr);
499 	*size32 = vm_sanitize_trunc_size_to_32(size);
500 
501 	return vm32_region_get_kern_return(kr, addr, size);
502 }
503 
504 kern_return_t
vm32_vm_region_recurse_64(vm_map_t map,vm32_address_ut * addr32,vm32_size_ut * size32,uint32_t * depth,vm_region_recurse_info_64_t info,mach_msg_type_number_t * infoCnt)505 vm32_vm_region_recurse_64(
506 	vm_map_t                map,
507 	vm32_address_ut        *addr32,
508 	vm32_size_ut           *size32,
509 	uint32_t               *depth,
510 	vm_region_recurse_info_64_t info,
511 	mach_msg_type_number_t *infoCnt)
512 {
513 	mach_vm_offset_ut addr;
514 	mach_vm_size_ut   size;
515 	kern_return_t     kr;
516 
517 	addr = vm_sanitize_expand_addr_to_64(*addr32);
518 	size = vm_sanitize_expand_size_to_64(*size32);
519 
520 	kr = mach_vm_region_recurse(map, &addr, &size, depth, info, infoCnt);
521 
522 	*addr32 = vm_sanitize_trunc_addr_to_32(addr);
523 	*size32 = vm_sanitize_trunc_size_to_32(size);
524 
525 	return kr;
526 }
527 
528 kern_return_t
vm32_vm_region_recurse(vm_map_t map,vm32_offset_ut * addr32,vm32_size_ut * size32,natural_t * depth,vm_region_recurse_info_t info32,mach_msg_type_number_t * infoCnt)529 vm32_vm_region_recurse(
530 	vm_map_t                map,
531 	vm32_offset_ut         *addr32,         /* IN/OUT */
532 	vm32_size_ut           *size32,         /* OUT */
533 	natural_t              *depth,          /* IN/OUT */
534 	vm_region_recurse_info_t info32,        /* IN/OUT */
535 	mach_msg_type_number_t *infoCnt)        /* IN/OUT */
536 {
537 	vm_region_submap_info_data_64_t info64;
538 	vm_region_submap_info_t info;
539 	mach_vm_offset_ut       addr;
540 	mach_vm_size_ut         size;
541 	kern_return_t           kr;
542 
543 	if (VM_MAP_NULL == map || *infoCnt < VM_REGION_SUBMAP_INFO_COUNT) {
544 		return KERN_INVALID_ARGUMENT;
545 	}
546 
547 
548 	addr = vm_sanitize_expand_addr_to_64(*addr32);
549 	size = vm_sanitize_expand_size_to_64(*size32);
550 	info = (vm_region_submap_info_t)info32;
551 	*infoCnt = VM_REGION_SUBMAP_INFO_COUNT_64;
552 
553 	kr = mach_vm_region_recurse(map, &addr, &size,
554 	    depth, (vm_region_recurse_info_t)&info64, infoCnt);
555 
556 	info->protection = info64.protection;
557 	info->max_protection = info64.max_protection;
558 	info->inheritance = info64.inheritance;
559 	info->offset = (uint32_t)info64.offset; /* trouble-maker */
560 	info->user_tag = info64.user_tag;
561 	info->pages_resident = info64.pages_resident;
562 	info->pages_shared_now_private = info64.pages_shared_now_private;
563 	info->pages_swapped_out = info64.pages_swapped_out;
564 	info->pages_dirtied = info64.pages_dirtied;
565 	info->ref_count = info64.ref_count;
566 	info->shadow_depth = info64.shadow_depth;
567 	info->external_pager = info64.external_pager;
568 	info->share_mode = info64.share_mode;
569 	info->is_submap = info64.is_submap;
570 	info->behavior = info64.behavior;
571 	info->object_id = info64.object_id;
572 	info->user_wired_count = info64.user_wired_count;
573 
574 	*addr32 = vm_sanitize_trunc_addr_to_32(addr);
575 	*size32 = vm_sanitize_trunc_size_to_32(size);
576 	*infoCnt = VM_REGION_SUBMAP_INFO_COUNT;
577 
578 	return vm32_region_get_kern_return(kr, addr, size);
579 }
580 
581 kern_return_t
vm32_vm_purgable_control(vm_map_t map,vm32_offset_ut addr32,vm_purgable_t control,int * state)582 vm32_vm_purgable_control(
583 	vm_map_t                map,
584 	vm32_offset_ut          addr32,
585 	vm_purgable_t           control,
586 	int                    *state)
587 {
588 	mach_vm_offset_ut addr;
589 
590 	addr = vm_sanitize_expand_addr_to_64(addr32);
591 	return mach_vm_purgable_control(map, addr, control, state);
592 }
593 
594 kern_return_t
vm32_vm_map_page_query(vm_map_t map,vm32_offset_t offset32,int * disposition,int * ref_count)595 vm32_vm_map_page_query(
596 	vm_map_t                map,
597 	vm32_offset_t           offset32,
598 	int                     *disposition,
599 	int                     *ref_count)
600 {
601 	vm_offset_ut offset = vm_sanitize_expand_addr_to_64(offset32);
602 
603 	return mach_vm_page_query(map, offset, disposition, ref_count);
604 }
605 
606 kern_return_t
vm32_mach_make_memory_entry_64(vm_map_t target_map,memory_object_size_ut * size,memory_object_offset_ut offset,vm_prot_ut permission,ipc_port_t * object_handle,ipc_port_t parent_handle)607 vm32_mach_make_memory_entry_64(
608 	vm_map_t                target_map,
609 	memory_object_size_ut  *size,
610 	memory_object_offset_ut offset,
611 	vm_prot_ut              permission,
612 	ipc_port_t              *object_handle,
613 	ipc_port_t              parent_handle)
614 {
615 	// use the existing entrypoint
616 	return _mach_make_memory_entry(target_map, size, offset, permission, object_handle, parent_handle);
617 }
618 
619 kern_return_t
vm32_mach_make_memory_entry(vm_map_t target_map,vm32_size_ut * size,vm32_offset_ut offset,vm_prot_ut permission,ipc_port_t * object_handle,ipc_port_t parent_entry)620 vm32_mach_make_memory_entry(
621 	vm_map_t                target_map,
622 	vm32_size_ut           *size,
623 	vm32_offset_ut          offset,
624 	vm_prot_ut              permission,
625 	ipc_port_t              *object_handle,
626 	ipc_port_t              parent_entry)
627 {
628 	memory_object_size_ut   mo_size = vm_sanitize_expand_size_to_64(*size);
629 	memory_object_offset_ut mo_offset = vm_sanitize_expand_addr_to_64(offset);
630 	kern_return_t           kr;
631 
632 	kr = _mach_make_memory_entry(target_map, &mo_size,
633 	    mo_offset, permission, object_handle, parent_entry);
634 	*size = vm_sanitize_trunc_size_to_32(mo_size);
635 	return kr;
636 }
637 
638 kern_return_t
vm32_task_wire(vm_map_t map,boolean_t must_wire __unused)639 vm32_task_wire(
640 	vm_map_t        map,
641 	boolean_t       must_wire __unused)
642 {
643 	if (map == VM_MAP_NULL) {
644 		return KERN_INVALID_ARGUMENT;
645 	}
646 
647 	return KERN_NOT_SUPPORTED;
648 }
649 
650 kern_return_t
vm32_vm_map_exec_lockdown(vm_map_t map)651 vm32_vm_map_exec_lockdown(
652 	vm_map_t        map)
653 {
654 	if (map == VM_MAP_NULL) {
655 		return KERN_INVALID_ARGUMENT;
656 	}
657 
658 	vm_map_lock(map);
659 	map->map_disallow_new_exec = TRUE;
660 	vm_map_unlock(map);
661 
662 	return KERN_SUCCESS;
663 }
664 
665 
666 #endif /* VM32_SUPPORT */
667