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 vmlp_api_start(VM32__MAP_EXEC_LOCKDOWN);
655 vmlp_range_event_none(map);
656
657 if (map == VM_MAP_NULL) {
658 vmlp_api_end(VM32__MAP_EXEC_LOCKDOWN, KERN_INVALID_ARGUMENT);
659 return KERN_INVALID_ARGUMENT;
660 }
661
662 vm_map_lock(map);
663 map->map_disallow_new_exec = TRUE;
664 vm_map_unlock(map);
665
666 vmlp_api_end(VM32__MAP_EXEC_LOCKDOWN, KERN_SUCCESS);
667 return KERN_SUCCESS;
668 }
669
670
671 #endif /* VM32_SUPPORT */
672