]> git.saurik.com Git - apple/xnu.git/blob - bsd/vm/vm_unix.c
df5f607ae13951edf46b0fe9dd269ee21af94f57
[apple/xnu.git] / bsd / vm / vm_unix.c
1 /*
2 * Copyright (c) 2000-2018 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 * Mach Operating System
30 * Copyright (c) 1987 Carnegie-Mellon University
31 * All rights reserved. The CMU software License Agreement specifies
32 * the terms and conditions for use and redistribution.
33 */
34 /*
35 * NOTICE: This file was modified by SPARTA, Inc. in 2006 to introduce
36 * support for mandatory and extensible security protections. This notice
37 * is included in support of clause 2.2 (b) of the Apple Public License,
38 * Version 2.0.
39 */
40 #include <vm/vm_options.h>
41
42 #include <kern/task.h>
43 #include <kern/thread.h>
44 #include <kern/debug.h>
45 #include <kern/extmod_statistics.h>
46 #include <mach/mach_traps.h>
47 #include <mach/port.h>
48 #include <mach/sdt.h>
49 #include <mach/task.h>
50 #include <mach/task_access.h>
51 #include <mach/task_special_ports.h>
52 #include <mach/time_value.h>
53 #include <mach/vm_map.h>
54 #include <mach/vm_param.h>
55 #include <mach/vm_prot.h>
56
57 #include <sys/file_internal.h>
58 #include <sys/param.h>
59 #include <sys/systm.h>
60 #include <sys/dir.h>
61 #include <sys/namei.h>
62 #include <sys/proc_internal.h>
63 #include <sys/kauth.h>
64 #include <sys/vm.h>
65 #include <sys/file.h>
66 #include <sys/vnode_internal.h>
67 #include <sys/mount.h>
68 #include <sys/trace.h>
69 #include <sys/kernel.h>
70 #include <sys/ubc_internal.h>
71 #include <sys/user.h>
72 #include <sys/syslog.h>
73 #include <sys/stat.h>
74 #include <sys/sysproto.h>
75 #include <sys/mman.h>
76 #include <sys/sysctl.h>
77 #include <sys/cprotect.h>
78 #include <sys/kpi_socket.h>
79 #include <sys/kas_info.h>
80 #include <sys/socket.h>
81 #include <sys/socketvar.h>
82 #if NECP
83 #include <net/necp.h>
84 #endif /* NECP */
85
86 #include <security/audit/audit.h>
87 #include <security/mac.h>
88 #include <bsm/audit_kevents.h>
89
90 #include <kern/kalloc.h>
91 #include <vm/vm_map.h>
92 #include <vm/vm_kern.h>
93 #include <vm/vm_pageout.h>
94
95 #include <mach/shared_region.h>
96 #include <vm/vm_shared_region.h>
97
98 #include <vm/vm_protos.h>
99
100 #include <sys/kern_memorystatus.h>
101
102 #if CONFIG_MACF
103 #include <security/mac_framework.h>
104 #endif
105
106 int _shared_region_map_and_slide(struct proc*, int, unsigned int, struct shared_file_mapping_np*, uint32_t, user_addr_t, user_addr_t);
107 int shared_region_copyin_mappings(struct proc*, user_addr_t, unsigned int, struct shared_file_mapping_np *);
108
109 #if VM_MAP_DEBUG_APPLE_PROTECT
110 SYSCTL_INT(_vm, OID_AUTO, map_debug_apple_protect, CTLFLAG_RW | CTLFLAG_LOCKED, &vm_map_debug_apple_protect, 0, "");
111 #endif /* VM_MAP_DEBUG_APPLE_PROTECT */
112
113 #if VM_MAP_DEBUG_FOURK
114 SYSCTL_INT(_vm, OID_AUTO, map_debug_fourk, CTLFLAG_RW | CTLFLAG_LOCKED, &vm_map_debug_fourk, 0, "");
115 #endif /* VM_MAP_DEBUG_FOURK */
116
117 #if DEVELOPMENT || DEBUG
118
119 static int
120 sysctl_kmem_alloc_contig SYSCTL_HANDLER_ARGS
121 {
122 #pragma unused(arg1, arg2)
123 vm_offset_t kaddr;
124 kern_return_t kr;
125 int error = 0;
126 int size = 0;
127
128 error = sysctl_handle_int(oidp, &size, 0, req);
129 if (error || !req->newptr)
130 return (error);
131
132 kr = kmem_alloc_contig(kernel_map, &kaddr, (vm_size_t)size, 0, 0, 0, 0, VM_KERN_MEMORY_IOKIT);
133
134 if (kr == KERN_SUCCESS)
135 kmem_free(kernel_map, kaddr, size);
136
137 return error;
138 }
139
140 SYSCTL_PROC(_vm, OID_AUTO, kmem_alloc_contig, CTLTYPE_INT|CTLFLAG_WR|CTLFLAG_LOCKED|CTLFLAG_MASKED,
141 0, 0, &sysctl_kmem_alloc_contig, "I", "");
142
143 extern int vm_region_footprint;
144 SYSCTL_INT(_vm, OID_AUTO, region_footprint, CTLFLAG_RW | CTLFLAG_ANYBODY | CTLFLAG_LOCKED, &vm_region_footprint, 0, "");
145 static int
146 sysctl_vm_self_region_footprint SYSCTL_HANDLER_ARGS
147 {
148 #pragma unused(arg1, arg2, oidp)
149 int error = 0;
150 int value;
151
152 value = task_self_region_footprint();
153 error = SYSCTL_OUT(req, &value, sizeof (int));
154 if (error) {
155 return error;
156 }
157
158 if (!req->newptr) {
159 return 0;
160 }
161
162 error = SYSCTL_IN(req, &value, sizeof (int));
163 if (error) {
164 return (error);
165 }
166 task_self_region_footprint_set(value);
167 return 0;
168 }
169 SYSCTL_PROC(_vm, OID_AUTO, self_region_footprint, CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY|CTLFLAG_LOCKED|CTLFLAG_MASKED, 0, 0, &sysctl_vm_self_region_footprint, "I", "");
170
171 #endif /* DEVELOPMENT || DEBUG */
172
173
174 #if CONFIG_EMBEDDED
175
176 #if DEVELOPMENT || DEBUG
177 extern int panic_on_unsigned_execute;
178 SYSCTL_INT(_vm, OID_AUTO, panic_on_unsigned_execute, CTLFLAG_RW | CTLFLAG_LOCKED, &panic_on_unsigned_execute, 0, "");
179 #endif /* DEVELOPMENT || DEBUG */
180
181 extern int log_executable_mem_entry;
182 extern int cs_executable_create_upl;
183 extern int cs_executable_mem_entry;
184 extern int cs_executable_wire;
185 SYSCTL_INT(_vm, OID_AUTO, log_executable_mem_entry, CTLFLAG_RD | CTLFLAG_LOCKED, &log_executable_mem_entry, 0, "");
186 SYSCTL_INT(_vm, OID_AUTO, cs_executable_create_upl, CTLFLAG_RD | CTLFLAG_LOCKED, &cs_executable_create_upl, 0, "");
187 SYSCTL_INT(_vm, OID_AUTO, cs_executable_mem_entry, CTLFLAG_RD | CTLFLAG_LOCKED, &cs_executable_mem_entry, 0, "");
188 SYSCTL_INT(_vm, OID_AUTO, cs_executable_wire, CTLFLAG_RD | CTLFLAG_LOCKED, &cs_executable_wire, 0, "");
189 #endif /* CONFIG_EMBEDDED */
190
191 #if DEVELOPMENT || DEBUG
192 extern int radar_20146450;
193 SYSCTL_INT(_vm, OID_AUTO, radar_20146450, CTLFLAG_RW | CTLFLAG_LOCKED, &radar_20146450, 0, "");
194
195 extern int macho_printf;
196 SYSCTL_INT(_vm, OID_AUTO, macho_printf, CTLFLAG_RW | CTLFLAG_LOCKED, &macho_printf, 0, "");
197
198 extern int apple_protect_pager_data_request_debug;
199 SYSCTL_INT(_vm, OID_AUTO, apple_protect_pager_data_request_debug, CTLFLAG_RW | CTLFLAG_LOCKED, &apple_protect_pager_data_request_debug, 0, "");
200
201 #if __arm__ || __arm64__
202 /* These are meant to support the page table accounting unit test. */
203 extern unsigned int arm_hardware_page_size;
204 extern unsigned int arm_pt_desc_size;
205 extern unsigned int arm_pt_root_size;
206 extern unsigned int free_page_size_tt_count;
207 extern unsigned int free_two_page_size_tt_count;
208 extern unsigned int free_tt_count;
209 extern unsigned int inuse_user_tteroot_count;
210 extern unsigned int inuse_kernel_tteroot_count;
211 extern unsigned int inuse_user_ttepages_count;
212 extern unsigned int inuse_kernel_ttepages_count;
213 extern unsigned int inuse_user_ptepages_count;
214 extern unsigned int inuse_kernel_ptepages_count;
215 SYSCTL_UINT(_vm, OID_AUTO, native_hw_pagesize, CTLFLAG_RD | CTLFLAG_LOCKED, &arm_hardware_page_size, 0, "");
216 SYSCTL_UINT(_vm, OID_AUTO, arm_pt_desc_size, CTLFLAG_RD | CTLFLAG_LOCKED, &arm_pt_desc_size, 0, "");
217 SYSCTL_UINT(_vm, OID_AUTO, arm_pt_root_size, CTLFLAG_RD | CTLFLAG_LOCKED, &arm_pt_root_size, 0, "");
218 SYSCTL_UINT(_vm, OID_AUTO, free_1page_tte_root, CTLFLAG_RD | CTLFLAG_LOCKED, &free_page_size_tt_count, 0, "");
219 SYSCTL_UINT(_vm, OID_AUTO, free_2page_tte_root, CTLFLAG_RD | CTLFLAG_LOCKED, &free_two_page_size_tt_count, 0, "");
220 SYSCTL_UINT(_vm, OID_AUTO, free_tte_root, CTLFLAG_RD | CTLFLAG_LOCKED, &free_tt_count, 0, "");
221 SYSCTL_UINT(_vm, OID_AUTO, user_tte_root, CTLFLAG_RD | CTLFLAG_LOCKED, &inuse_user_tteroot_count, 0, "");
222 SYSCTL_UINT(_vm, OID_AUTO, kernel_tte_root, CTLFLAG_RD | CTLFLAG_LOCKED, &inuse_kernel_tteroot_count, 0, "");
223 SYSCTL_UINT(_vm, OID_AUTO, user_tte_pages, CTLFLAG_RD | CTLFLAG_LOCKED, &inuse_user_ttepages_count, 0, "");
224 SYSCTL_UINT(_vm, OID_AUTO, kernel_tte_pages, CTLFLAG_RD | CTLFLAG_LOCKED, &inuse_kernel_ttepages_count, 0, "");
225 SYSCTL_UINT(_vm, OID_AUTO, user_pte_pages, CTLFLAG_RD | CTLFLAG_LOCKED, &inuse_user_ptepages_count, 0, "");
226 SYSCTL_UINT(_vm, OID_AUTO, kernel_pte_pages, CTLFLAG_RD | CTLFLAG_LOCKED, &inuse_kernel_ptepages_count, 0, "");
227 #endif /* __arm__ || __arm64__ */
228
229 #if __arm64__
230 extern int fourk_pager_data_request_debug;
231 SYSCTL_INT(_vm, OID_AUTO, fourk_pager_data_request_debug, CTLFLAG_RW | CTLFLAG_LOCKED, &fourk_pager_data_request_debug, 0, "");
232 #endif /* __arm64__ */
233 #endif /* DEVELOPMENT || DEBUG */
234
235 SYSCTL_INT(_vm, OID_AUTO, vm_do_collapse_compressor, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_counters.do_collapse_compressor, 0, "");
236 SYSCTL_INT(_vm, OID_AUTO, vm_do_collapse_compressor_pages, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_counters.do_collapse_compressor_pages, 0, "");
237 SYSCTL_INT(_vm, OID_AUTO, vm_do_collapse_terminate, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_counters.do_collapse_terminate, 0, "");
238 SYSCTL_INT(_vm, OID_AUTO, vm_do_collapse_terminate_failure, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_counters.do_collapse_terminate_failure, 0, "");
239 SYSCTL_INT(_vm, OID_AUTO, vm_should_cow_but_wired, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_counters.should_cow_but_wired, 0, "");
240 SYSCTL_INT(_vm, OID_AUTO, vm_create_upl_extra_cow, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_counters.create_upl_extra_cow, 0, "");
241 SYSCTL_INT(_vm, OID_AUTO, vm_create_upl_extra_cow_pages, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_counters.create_upl_extra_cow_pages, 0, "");
242 SYSCTL_INT(_vm, OID_AUTO, vm_create_upl_lookup_failure_write, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_counters.create_upl_lookup_failure_write, 0, "");
243 SYSCTL_INT(_vm, OID_AUTO, vm_create_upl_lookup_failure_copy, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_counters.create_upl_lookup_failure_copy, 0, "");
244 #if VM_SCAN_FOR_SHADOW_CHAIN
245 static int vm_shadow_max_enabled = 0; /* Disabled by default */
246 extern int proc_shadow_max(void);
247 static int
248 vm_shadow_max SYSCTL_HANDLER_ARGS
249 {
250 #pragma unused(arg1, arg2, oidp)
251 int value = 0;
252
253 if (vm_shadow_max_enabled)
254 value = proc_shadow_max();
255
256 return SYSCTL_OUT(req, &value, sizeof(value));
257 }
258 SYSCTL_PROC(_vm, OID_AUTO, vm_shadow_max, CTLTYPE_INT|CTLFLAG_RD|CTLFLAG_LOCKED,
259 0, 0, &vm_shadow_max, "I", "");
260
261 SYSCTL_INT(_vm, OID_AUTO, vm_shadow_max_enabled, CTLFLAG_RW | CTLFLAG_LOCKED, &vm_shadow_max_enabled, 0, "");
262
263 #endif /* VM_SCAN_FOR_SHADOW_CHAIN */
264
265 SYSCTL_INT(_vm, OID_AUTO, vm_debug_events, CTLFLAG_RW | CTLFLAG_LOCKED, &vm_debug_events, 0, "");
266
267 __attribute__((noinline)) int __KERNEL_WAITING_ON_TASKGATED_CHECK_ACCESS_UPCALL__(
268 mach_port_t task_access_port, int32_t calling_pid, uint32_t calling_gid, int32_t target_pid);
269 /*
270 * Sysctl's related to data/stack execution. See osfmk/vm/vm_map.c
271 */
272
273 #if DEVELOPMENT || DEBUG
274 extern int allow_stack_exec, allow_data_exec;
275
276 SYSCTL_INT(_vm, OID_AUTO, allow_stack_exec, CTLFLAG_RW | CTLFLAG_LOCKED, &allow_stack_exec, 0, "");
277 SYSCTL_INT(_vm, OID_AUTO, allow_data_exec, CTLFLAG_RW | CTLFLAG_LOCKED, &allow_data_exec, 0, "");
278
279 #if __arm64__
280 extern int fourk_binary_compatibility_unsafe;
281 extern int fourk_binary_compatibility_allow_wx;
282 SYSCTL_INT(_vm, OID_AUTO, fourk_binary_compatibility_unsafe, CTLFLAG_RW | CTLFLAG_LOCKED, &fourk_binary_compatibility_unsafe, 0, "");
283 SYSCTL_INT(_vm, OID_AUTO, fourk_binary_compatibility_allow_wx, CTLFLAG_RW | CTLFLAG_LOCKED, &fourk_binary_compatibility_allow_wx, 0, "");
284 #endif /* __arm64__ */
285 #endif /* DEVELOPMENT || DEBUG */
286
287 static const char *prot_values[] = {
288 "none",
289 "read-only",
290 "write-only",
291 "read-write",
292 "execute-only",
293 "read-execute",
294 "write-execute",
295 "read-write-execute"
296 };
297
298 void
299 log_stack_execution_failure(addr64_t vaddr, vm_prot_t prot)
300 {
301 printf("Data/Stack execution not permitted: %s[pid %d] at virtual address 0x%qx, protections were %s\n",
302 current_proc()->p_comm, current_proc()->p_pid, vaddr, prot_values[prot & VM_PROT_ALL]);
303 }
304
305 /*
306 * shared_region_unnest_logging: level of logging of unnesting events
307 * 0 - no logging
308 * 1 - throttled logging of unexpected unnesting events (default)
309 * 2 - unthrottled logging of unexpected unnesting events
310 * 3+ - unthrottled logging of all unnesting events
311 */
312 int shared_region_unnest_logging = 1;
313
314 SYSCTL_INT(_vm, OID_AUTO, shared_region_unnest_logging, CTLFLAG_RW | CTLFLAG_LOCKED,
315 &shared_region_unnest_logging, 0, "");
316
317 int vm_shared_region_unnest_log_interval = 10;
318 int shared_region_unnest_log_count_threshold = 5;
319
320 /*
321 * Shared cache path enforcement.
322 */
323
324 #ifndef CONFIG_EMBEDDED
325 static int scdir_enforce = 1;
326 static char scdir_path[] = "/var/db/dyld/";
327 #else
328 static int scdir_enforce = 0;
329 static char scdir_path[] = "/System/Library/Caches/com.apple.dyld/";
330 #endif
331
332 #ifndef SECURE_KERNEL
333 SYSCTL_INT(_vm, OID_AUTO, enforce_shared_cache_dir, CTLFLAG_RW | CTLFLAG_LOCKED, &scdir_enforce, 0, "");
334 #endif
335
336 /* These log rate throttling state variables aren't thread safe, but
337 * are sufficient unto the task.
338 */
339 static int64_t last_unnest_log_time = 0;
340 static int shared_region_unnest_log_count = 0;
341
342 void
343 log_unnest_badness(
344 vm_map_t m,
345 vm_map_offset_t s,
346 vm_map_offset_t e,
347 boolean_t is_nested_map,
348 vm_map_offset_t lowest_unnestable_addr)
349 {
350 struct timeval tv;
351
352 if (shared_region_unnest_logging == 0)
353 return;
354
355 if (shared_region_unnest_logging <= 2 &&
356 is_nested_map &&
357 s >= lowest_unnestable_addr) {
358 /*
359 * Unnesting of writable map entries is fine.
360 */
361 return;
362 }
363
364 if (shared_region_unnest_logging <= 1) {
365 microtime(&tv);
366 if ((tv.tv_sec - last_unnest_log_time) <
367 vm_shared_region_unnest_log_interval) {
368 if (shared_region_unnest_log_count++ >
369 shared_region_unnest_log_count_threshold)
370 return;
371 } else {
372 last_unnest_log_time = tv.tv_sec;
373 shared_region_unnest_log_count = 0;
374 }
375 }
376
377 DTRACE_VM4(log_unnest_badness,
378 vm_map_t, m,
379 vm_map_offset_t, s,
380 vm_map_offset_t, e,
381 vm_map_offset_t, lowest_unnestable_addr);
382 printf("%s[%d] triggered unnest of range 0x%qx->0x%qx of DYLD shared region in VM map %p. While not abnormal for debuggers, this increases system memory footprint until the target exits.\n", current_proc()->p_comm, current_proc()->p_pid, (uint64_t)s, (uint64_t)e, (void *) VM_KERNEL_ADDRPERM(m));
383 }
384
385 int
386 useracc(
387 user_addr_t addr,
388 user_size_t len,
389 int prot)
390 {
391 vm_map_t map;
392
393 map = current_map();
394 return (vm_map_check_protection(
395 map,
396 vm_map_trunc_page(addr,
397 vm_map_page_mask(map)),
398 vm_map_round_page(addr+len,
399 vm_map_page_mask(map)),
400 prot == B_READ ? VM_PROT_READ : VM_PROT_WRITE));
401 }
402
403 int
404 vslock(
405 user_addr_t addr,
406 user_size_t len)
407 {
408 kern_return_t kret;
409 vm_map_t map;
410
411 map = current_map();
412 kret = vm_map_wire_kernel(map,
413 vm_map_trunc_page(addr,
414 vm_map_page_mask(map)),
415 vm_map_round_page(addr+len,
416 vm_map_page_mask(map)),
417 VM_PROT_READ | VM_PROT_WRITE, VM_KERN_MEMORY_BSD,
418 FALSE);
419
420 switch (kret) {
421 case KERN_SUCCESS:
422 return (0);
423 case KERN_INVALID_ADDRESS:
424 case KERN_NO_SPACE:
425 return (ENOMEM);
426 case KERN_PROTECTION_FAILURE:
427 return (EACCES);
428 default:
429 return (EINVAL);
430 }
431 }
432
433 int
434 vsunlock(
435 user_addr_t addr,
436 user_size_t len,
437 __unused int dirtied)
438 {
439 #if FIXME /* [ */
440 pmap_t pmap;
441 vm_page_t pg;
442 vm_map_offset_t vaddr;
443 ppnum_t paddr;
444 #endif /* FIXME ] */
445 kern_return_t kret;
446 vm_map_t map;
447
448 map = current_map();
449
450 #if FIXME /* [ */
451 if (dirtied) {
452 pmap = get_task_pmap(current_task());
453 for (vaddr = vm_map_trunc_page(addr, PAGE_MASK);
454 vaddr < vm_map_round_page(addr+len, PAGE_MASK);
455 vaddr += PAGE_SIZE) {
456 paddr = pmap_extract(pmap, vaddr);
457 pg = PHYS_TO_VM_PAGE(paddr);
458 vm_page_set_modified(pg);
459 }
460 }
461 #endif /* FIXME ] */
462 #ifdef lint
463 dirtied++;
464 #endif /* lint */
465 kret = vm_map_unwire(map,
466 vm_map_trunc_page(addr,
467 vm_map_page_mask(map)),
468 vm_map_round_page(addr+len,
469 vm_map_page_mask(map)),
470 FALSE);
471 switch (kret) {
472 case KERN_SUCCESS:
473 return (0);
474 case KERN_INVALID_ADDRESS:
475 case KERN_NO_SPACE:
476 return (ENOMEM);
477 case KERN_PROTECTION_FAILURE:
478 return (EACCES);
479 default:
480 return (EINVAL);
481 }
482 }
483
484 int
485 subyte(
486 user_addr_t addr,
487 int byte)
488 {
489 char character;
490
491 character = (char)byte;
492 return (copyout((void *)&(character), addr, sizeof(char)) == 0 ? 0 : -1);
493 }
494
495 int
496 suibyte(
497 user_addr_t addr,
498 int byte)
499 {
500 char character;
501
502 character = (char)byte;
503 return (copyout((void *)&(character), addr, sizeof(char)) == 0 ? 0 : -1);
504 }
505
506 int fubyte(user_addr_t addr)
507 {
508 unsigned char byte;
509
510 if (copyin(addr, (void *) &byte, sizeof(char)))
511 return(-1);
512 return(byte);
513 }
514
515 int fuibyte(user_addr_t addr)
516 {
517 unsigned char byte;
518
519 if (copyin(addr, (void *) &(byte), sizeof(char)))
520 return(-1);
521 return(byte);
522 }
523
524 int
525 suword(
526 user_addr_t addr,
527 long word)
528 {
529 return (copyout((void *) &word, addr, sizeof(int)) == 0 ? 0 : -1);
530 }
531
532 long fuword(user_addr_t addr)
533 {
534 long word = 0;
535
536 if (copyin(addr, (void *) &word, sizeof(int)))
537 return(-1);
538 return(word);
539 }
540
541 /* suiword and fuiword are the same as suword and fuword, respectively */
542
543 int
544 suiword(
545 user_addr_t addr,
546 long word)
547 {
548 return (copyout((void *) &word, addr, sizeof(int)) == 0 ? 0 : -1);
549 }
550
551 long fuiword(user_addr_t addr)
552 {
553 long word = 0;
554
555 if (copyin(addr, (void *) &word, sizeof(int)))
556 return(-1);
557 return(word);
558 }
559
560 /*
561 * With a 32-bit kernel and mixed 32/64-bit user tasks, this interface allows the
562 * fetching and setting of process-sized size_t and pointer values.
563 */
564 int
565 sulong(user_addr_t addr, int64_t word)
566 {
567
568 if (IS_64BIT_PROCESS(current_proc())) {
569 return(copyout((void *)&word, addr, sizeof(word)) == 0 ? 0 : -1);
570 } else {
571 return(suiword(addr, (long)word));
572 }
573 }
574
575 int64_t
576 fulong(user_addr_t addr)
577 {
578 int64_t longword;
579
580 if (IS_64BIT_PROCESS(current_proc())) {
581 if (copyin(addr, (void *)&longword, sizeof(longword)) != 0)
582 return(-1);
583 return(longword);
584 } else {
585 return((int64_t)fuiword(addr));
586 }
587 }
588
589 int
590 suulong(user_addr_t addr, uint64_t uword)
591 {
592
593 if (IS_64BIT_PROCESS(current_proc())) {
594 return(copyout((void *)&uword, addr, sizeof(uword)) == 0 ? 0 : -1);
595 } else {
596 return(suiword(addr, (uint32_t)uword));
597 }
598 }
599
600 uint64_t
601 fuulong(user_addr_t addr)
602 {
603 uint64_t ulongword;
604
605 if (IS_64BIT_PROCESS(current_proc())) {
606 if (copyin(addr, (void *)&ulongword, sizeof(ulongword)) != 0)
607 return(-1ULL);
608 return(ulongword);
609 } else {
610 return((uint64_t)fuiword(addr));
611 }
612 }
613
614 int
615 swapon(__unused proc_t procp, __unused struct swapon_args *uap, __unused int *retval)
616 {
617 return(ENOTSUP);
618 }
619
620 /*
621 * pid_for_task
622 *
623 * Find the BSD process ID for the Mach task associated with the given Mach port
624 * name
625 *
626 * Parameters: args User argument descriptor (see below)
627 *
628 * Indirect parameters: args->t Mach port name
629 * args->pid Process ID (returned value; see below)
630 *
631 * Returns: KERL_SUCCESS Success
632 * KERN_FAILURE Not success
633 *
634 * Implicit returns: args->pid Process ID
635 *
636 */
637 kern_return_t
638 pid_for_task(
639 struct pid_for_task_args *args)
640 {
641 mach_port_name_t t = args->t;
642 user_addr_t pid_addr = args->pid;
643 proc_t p;
644 task_t t1;
645 int pid = -1;
646 kern_return_t err = KERN_SUCCESS;
647
648 AUDIT_MACH_SYSCALL_ENTER(AUE_PIDFORTASK);
649 AUDIT_ARG(mach_port1, t);
650
651 t1 = port_name_to_task_inspect(t);
652
653 if (t1 == TASK_NULL) {
654 err = KERN_FAILURE;
655 goto pftout;
656 } else {
657 p = get_bsdtask_info(t1);
658 if (p) {
659 pid = proc_pid(p);
660 err = KERN_SUCCESS;
661 } else if (is_corpsetask(t1)) {
662 pid = task_pid(t1);
663 err = KERN_SUCCESS;
664 }else {
665 err = KERN_FAILURE;
666 }
667 }
668 task_deallocate(t1);
669 pftout:
670 AUDIT_ARG(pid, pid);
671 (void) copyout((char *) &pid, pid_addr, sizeof(int));
672 AUDIT_MACH_SYSCALL_EXIT(err);
673 return(err);
674 }
675
676 /*
677 *
678 * tfp_policy = KERN_TFP_POLICY_DENY; Deny Mode: None allowed except for self
679 * tfp_policy = KERN_TFP_POLICY_DEFAULT; default mode: all posix checks and upcall via task port for authentication
680 *
681 */
682 static int tfp_policy = KERN_TFP_POLICY_DEFAULT;
683
684 /*
685 * Routine: task_for_pid_posix_check
686 * Purpose:
687 * Verify that the current process should be allowed to
688 * get the target process's task port. This is only
689 * permitted if:
690 * - The current process is root
691 * OR all of the following are true:
692 * - The target process's real, effective, and saved uids
693 * are the same as the current proc's euid,
694 * - The target process's group set is a subset of the
695 * calling process's group set, and
696 * - The target process hasn't switched credentials.
697 *
698 * Returns: TRUE: permitted
699 * FALSE: denied
700 */
701 static int
702 task_for_pid_posix_check(proc_t target)
703 {
704 kauth_cred_t targetcred, mycred;
705 uid_t myuid;
706 int allowed;
707
708 /* No task_for_pid on bad targets */
709 if (target->p_stat == SZOMB) {
710 return FALSE;
711 }
712
713 mycred = kauth_cred_get();
714 myuid = kauth_cred_getuid(mycred);
715
716 /* If we're running as root, the check passes */
717 if (kauth_cred_issuser(mycred))
718 return TRUE;
719
720 /* We're allowed to get our own task port */
721 if (target == current_proc())
722 return TRUE;
723
724 /*
725 * Under DENY, only root can get another proc's task port,
726 * so no more checks are needed.
727 */
728 if (tfp_policy == KERN_TFP_POLICY_DENY) {
729 return FALSE;
730 }
731
732 targetcred = kauth_cred_proc_ref(target);
733 allowed = TRUE;
734
735 /* Do target's ruid, euid, and saved uid match my euid? */
736 if ((kauth_cred_getuid(targetcred) != myuid) ||
737 (kauth_cred_getruid(targetcred) != myuid) ||
738 (kauth_cred_getsvuid(targetcred) != myuid)) {
739 allowed = FALSE;
740 goto out;
741 }
742
743 /* Are target's groups a subset of my groups? */
744 if (kauth_cred_gid_subset(targetcred, mycred, &allowed) ||
745 allowed == 0) {
746 allowed = FALSE;
747 goto out;
748 }
749
750 /* Has target switched credentials? */
751 if (target->p_flag & P_SUGID) {
752 allowed = FALSE;
753 goto out;
754 }
755
756 out:
757 kauth_cred_unref(&targetcred);
758 return allowed;
759 }
760
761 /*
762 * __KERNEL_WAITING_ON_TASKGATED_CHECK_ACCESS_UPCALL__
763 *
764 * Description: Waits for the user space daemon to respond to the request
765 * we made. Function declared non inline to be visible in
766 * stackshots and spindumps as well as debugging.
767 */
768 __attribute__((noinline)) int __KERNEL_WAITING_ON_TASKGATED_CHECK_ACCESS_UPCALL__(
769 mach_port_t task_access_port, int32_t calling_pid, uint32_t calling_gid, int32_t target_pid)
770 {
771 return check_task_access(task_access_port, calling_pid, calling_gid, target_pid);
772 }
773
774 /*
775 * Routine: task_for_pid
776 * Purpose:
777 * Get the task port for another "process", named by its
778 * process ID on the same host as "target_task".
779 *
780 * Only permitted to privileged processes, or processes
781 * with the same user ID.
782 *
783 * Note: if pid == 0, an error is return no matter who is calling.
784 *
785 * XXX This should be a BSD system call, not a Mach trap!!!
786 */
787 kern_return_t
788 task_for_pid(
789 struct task_for_pid_args *args)
790 {
791 mach_port_name_t target_tport = args->target_tport;
792 int pid = args->pid;
793 user_addr_t task_addr = args->t;
794 proc_t p = PROC_NULL;
795 task_t t1 = TASK_NULL;
796 task_t task = TASK_NULL;
797 mach_port_name_t tret = MACH_PORT_NULL;
798 ipc_port_t tfpport = MACH_PORT_NULL;
799 void * sright;
800 int error = 0;
801
802 AUDIT_MACH_SYSCALL_ENTER(AUE_TASKFORPID);
803 AUDIT_ARG(pid, pid);
804 AUDIT_ARG(mach_port1, target_tport);
805
806 /* Always check if pid == 0 */
807 if (pid == 0) {
808 (void ) copyout((char *)&t1, task_addr, sizeof(mach_port_name_t));
809 AUDIT_MACH_SYSCALL_EXIT(KERN_FAILURE);
810 return(KERN_FAILURE);
811 }
812
813 t1 = port_name_to_task(target_tport);
814 if (t1 == TASK_NULL) {
815 (void) copyout((char *)&t1, task_addr, sizeof(mach_port_name_t));
816 AUDIT_MACH_SYSCALL_EXIT(KERN_FAILURE);
817 return(KERN_FAILURE);
818 }
819
820
821 p = proc_find(pid);
822 if (p == PROC_NULL) {
823 error = KERN_FAILURE;
824 goto tfpout;
825 }
826
827 #if CONFIG_AUDIT
828 AUDIT_ARG(process, p);
829 #endif
830
831 if (!(task_for_pid_posix_check(p))) {
832 error = KERN_FAILURE;
833 goto tfpout;
834 }
835
836 if (p->task == TASK_NULL) {
837 error = KERN_SUCCESS;
838 goto tfpout;
839 }
840
841 #if CONFIG_MACF
842 error = mac_proc_check_get_task(kauth_cred_get(), p);
843 if (error) {
844 error = KERN_FAILURE;
845 goto tfpout;
846 }
847 #endif
848
849 /* Grab a task reference since the proc ref might be dropped if an upcall to task access server is made */
850 task = p->task;
851 task_reference(task);
852
853 /* If we aren't root and target's task access port is set... */
854 if (!kauth_cred_issuser(kauth_cred_get()) &&
855 p != current_proc() &&
856 (task_get_task_access_port(task, &tfpport) == 0) &&
857 (tfpport != IPC_PORT_NULL)) {
858
859 if (tfpport == IPC_PORT_DEAD) {
860 error = KERN_PROTECTION_FAILURE;
861 goto tfpout;
862 }
863
864 /*
865 * Drop the proc_find proc ref before making an upcall
866 * to taskgated, since holding a proc_find
867 * ref while making an upcall can cause deadlock.
868 */
869 proc_rele(p);
870 p = PROC_NULL;
871
872 /* Call up to the task access server */
873 error = __KERNEL_WAITING_ON_TASKGATED_CHECK_ACCESS_UPCALL__(tfpport, proc_selfpid(), kauth_getgid(), pid);
874
875 if (error != MACH_MSG_SUCCESS) {
876 if (error == MACH_RCV_INTERRUPTED)
877 error = KERN_ABORTED;
878 else
879 error = KERN_FAILURE;
880 goto tfpout;
881 }
882 }
883
884 /* Grant task port access */
885 extmod_statistics_incr_task_for_pid(task);
886 sright = (void *) convert_task_to_port(task);
887
888 /* Check if the task has been corpsified */
889 if (is_corpsetask(task)) {
890 /* task ref consumed by convert_task_to_port */
891 task = TASK_NULL;
892 ipc_port_release_send(sright);
893 error = KERN_FAILURE;
894 goto tfpout;
895 }
896
897 /* task ref consumed by convert_task_to_port */
898 task = TASK_NULL;
899 tret = ipc_port_copyout_send(
900 sright,
901 get_task_ipcspace(current_task()));
902
903 error = KERN_SUCCESS;
904
905 tfpout:
906 task_deallocate(t1);
907 AUDIT_ARG(mach_port2, tret);
908 (void) copyout((char *) &tret, task_addr, sizeof(mach_port_name_t));
909
910 if (tfpport != IPC_PORT_NULL) {
911 ipc_port_release_send(tfpport);
912 }
913 if (task != TASK_NULL) {
914 task_deallocate(task);
915 }
916 if (p != PROC_NULL)
917 proc_rele(p);
918 AUDIT_MACH_SYSCALL_EXIT(error);
919 return(error);
920 }
921
922 /*
923 * Routine: task_name_for_pid
924 * Purpose:
925 * Get the task name port for another "process", named by its
926 * process ID on the same host as "target_task".
927 *
928 * Only permitted to privileged processes, or processes
929 * with the same user ID.
930 *
931 * XXX This should be a BSD system call, not a Mach trap!!!
932 */
933
934 kern_return_t
935 task_name_for_pid(
936 struct task_name_for_pid_args *args)
937 {
938 mach_port_name_t target_tport = args->target_tport;
939 int pid = args->pid;
940 user_addr_t task_addr = args->t;
941 proc_t p = PROC_NULL;
942 task_t t1;
943 mach_port_name_t tret;
944 void * sright;
945 int error = 0, refheld = 0;
946 kauth_cred_t target_cred;
947
948 AUDIT_MACH_SYSCALL_ENTER(AUE_TASKNAMEFORPID);
949 AUDIT_ARG(pid, pid);
950 AUDIT_ARG(mach_port1, target_tport);
951
952 t1 = port_name_to_task(target_tport);
953 if (t1 == TASK_NULL) {
954 (void) copyout((char *)&t1, task_addr, sizeof(mach_port_name_t));
955 AUDIT_MACH_SYSCALL_EXIT(KERN_FAILURE);
956 return(KERN_FAILURE);
957 }
958
959 p = proc_find(pid);
960 if (p != PROC_NULL) {
961 AUDIT_ARG(process, p);
962 target_cred = kauth_cred_proc_ref(p);
963 refheld = 1;
964
965 if ((p->p_stat != SZOMB)
966 && ((current_proc() == p)
967 || kauth_cred_issuser(kauth_cred_get())
968 || ((kauth_cred_getuid(target_cred) == kauth_cred_getuid(kauth_cred_get())) &&
969 ((kauth_cred_getruid(target_cred) == kauth_getruid()))))) {
970
971 if (p->task != TASK_NULL) {
972 task_reference(p->task);
973 #if CONFIG_MACF
974 error = mac_proc_check_get_task_name(kauth_cred_get(), p);
975 if (error) {
976 task_deallocate(p->task);
977 goto noperm;
978 }
979 #endif
980 sright = (void *)convert_task_name_to_port(p->task);
981 tret = ipc_port_copyout_send(sright,
982 get_task_ipcspace(current_task()));
983 } else
984 tret = MACH_PORT_NULL;
985
986 AUDIT_ARG(mach_port2, tret);
987 (void) copyout((char *)&tret, task_addr, sizeof(mach_port_name_t));
988 task_deallocate(t1);
989 error = KERN_SUCCESS;
990 goto tnfpout;
991 }
992 }
993
994 #if CONFIG_MACF
995 noperm:
996 #endif
997 task_deallocate(t1);
998 tret = MACH_PORT_NULL;
999 (void) copyout((char *) &tret, task_addr, sizeof(mach_port_name_t));
1000 error = KERN_FAILURE;
1001 tnfpout:
1002 if (refheld != 0)
1003 kauth_cred_unref(&target_cred);
1004 if (p != PROC_NULL)
1005 proc_rele(p);
1006 AUDIT_MACH_SYSCALL_EXIT(error);
1007 return(error);
1008 }
1009
1010 kern_return_t
1011 pid_suspend(struct proc *p __unused, struct pid_suspend_args *args, int *ret)
1012 {
1013 task_t target = NULL;
1014 proc_t targetproc = PROC_NULL;
1015 int pid = args->pid;
1016 int error = 0;
1017
1018 #if CONFIG_MACF
1019 error = mac_proc_check_suspend_resume(p, MAC_PROC_CHECK_SUSPEND);
1020 if (error) {
1021 error = EPERM;
1022 goto out;
1023 }
1024 #endif
1025
1026 if (pid == 0) {
1027 error = EPERM;
1028 goto out;
1029 }
1030
1031 targetproc = proc_find(pid);
1032 if (targetproc == PROC_NULL) {
1033 error = ESRCH;
1034 goto out;
1035 }
1036
1037 if (!task_for_pid_posix_check(targetproc)) {
1038 error = EPERM;
1039 goto out;
1040 }
1041
1042 target = targetproc->task;
1043 #ifndef CONFIG_EMBEDDED
1044 if (target != TASK_NULL) {
1045 mach_port_t tfpport;
1046
1047 /* If we aren't root and target's task access port is set... */
1048 if (!kauth_cred_issuser(kauth_cred_get()) &&
1049 targetproc != current_proc() &&
1050 (task_get_task_access_port(target, &tfpport) == 0) &&
1051 (tfpport != IPC_PORT_NULL)) {
1052
1053 if (tfpport == IPC_PORT_DEAD) {
1054 error = EACCES;
1055 goto out;
1056 }
1057
1058 /* Call up to the task access server */
1059 error = __KERNEL_WAITING_ON_TASKGATED_CHECK_ACCESS_UPCALL__(tfpport, proc_selfpid(), kauth_getgid(), pid);
1060
1061 if (error != MACH_MSG_SUCCESS) {
1062 if (error == MACH_RCV_INTERRUPTED)
1063 error = EINTR;
1064 else
1065 error = EPERM;
1066 goto out;
1067 }
1068 }
1069 }
1070 #endif
1071
1072 task_reference(target);
1073 error = task_pidsuspend(target);
1074 if (error) {
1075 if (error == KERN_INVALID_ARGUMENT) {
1076 error = EINVAL;
1077 } else {
1078 error = EPERM;
1079 }
1080 }
1081 #if CONFIG_MEMORYSTATUS
1082 else {
1083 memorystatus_on_suspend(targetproc);
1084 }
1085 #endif
1086
1087 task_deallocate(target);
1088
1089 out:
1090 if (targetproc != PROC_NULL)
1091 proc_rele(targetproc);
1092 *ret = error;
1093 return error;
1094 }
1095
1096 kern_return_t
1097 pid_resume(struct proc *p __unused, struct pid_resume_args *args, int *ret)
1098 {
1099 task_t target = NULL;
1100 proc_t targetproc = PROC_NULL;
1101 int pid = args->pid;
1102 int error = 0;
1103
1104 #if CONFIG_MACF
1105 error = mac_proc_check_suspend_resume(p, MAC_PROC_CHECK_RESUME);
1106 if (error) {
1107 error = EPERM;
1108 goto out;
1109 }
1110 #endif
1111
1112 if (pid == 0) {
1113 error = EPERM;
1114 goto out;
1115 }
1116
1117 targetproc = proc_find(pid);
1118 if (targetproc == PROC_NULL) {
1119 error = ESRCH;
1120 goto out;
1121 }
1122
1123 if (!task_for_pid_posix_check(targetproc)) {
1124 error = EPERM;
1125 goto out;
1126 }
1127
1128 target = targetproc->task;
1129 #ifndef CONFIG_EMBEDDED
1130 if (target != TASK_NULL) {
1131 mach_port_t tfpport;
1132
1133 /* If we aren't root and target's task access port is set... */
1134 if (!kauth_cred_issuser(kauth_cred_get()) &&
1135 targetproc != current_proc() &&
1136 (task_get_task_access_port(target, &tfpport) == 0) &&
1137 (tfpport != IPC_PORT_NULL)) {
1138
1139 if (tfpport == IPC_PORT_DEAD) {
1140 error = EACCES;
1141 goto out;
1142 }
1143
1144 /* Call up to the task access server */
1145 error = __KERNEL_WAITING_ON_TASKGATED_CHECK_ACCESS_UPCALL__(tfpport, proc_selfpid(), kauth_getgid(), pid);
1146
1147 if (error != MACH_MSG_SUCCESS) {
1148 if (error == MACH_RCV_INTERRUPTED)
1149 error = EINTR;
1150 else
1151 error = EPERM;
1152 goto out;
1153 }
1154 }
1155 }
1156 #endif
1157
1158 #if CONFIG_EMBEDDED
1159 #if SOCKETS
1160 resume_proc_sockets(targetproc);
1161 #endif /* SOCKETS */
1162 #endif /* CONFIG_EMBEDDED */
1163
1164 task_reference(target);
1165
1166 #if CONFIG_MEMORYSTATUS
1167 memorystatus_on_resume(targetproc);
1168 #endif
1169
1170 error = task_pidresume(target);
1171 if (error) {
1172 if (error == KERN_INVALID_ARGUMENT) {
1173 error = EINVAL;
1174 } else {
1175 if (error == KERN_MEMORY_ERROR) {
1176 psignal(targetproc, SIGKILL);
1177 error = EIO;
1178 } else
1179 error = EPERM;
1180 }
1181 }
1182
1183 task_deallocate(target);
1184
1185 out:
1186 if (targetproc != PROC_NULL)
1187 proc_rele(targetproc);
1188
1189 *ret = error;
1190 return error;
1191 }
1192
1193 #if CONFIG_EMBEDDED
1194 /*
1195 * Freeze the specified process (provided in args->pid), or find and freeze a PID.
1196 * When a process is specified, this call is blocking, otherwise we wake up the
1197 * freezer thread and do not block on a process being frozen.
1198 */
1199 kern_return_t
1200 pid_hibernate(struct proc *p __unused, struct pid_hibernate_args *args, int *ret)
1201 {
1202 int error = 0;
1203 proc_t targetproc = PROC_NULL;
1204 int pid = args->pid;
1205
1206 #ifndef CONFIG_FREEZE
1207 #pragma unused(pid)
1208 #else
1209
1210 #if CONFIG_MACF
1211 error = mac_proc_check_suspend_resume(p, MAC_PROC_CHECK_HIBERNATE);
1212 if (error) {
1213 error = EPERM;
1214 goto out;
1215 }
1216 #endif
1217
1218 /*
1219 * If a pid has been provided, we obtain the process handle and call task_for_pid_posix_check().
1220 */
1221
1222 if (pid >= 0) {
1223 targetproc = proc_find(pid);
1224
1225 if (targetproc == PROC_NULL) {
1226 error = ESRCH;
1227 goto out;
1228 }
1229
1230 if (!task_for_pid_posix_check(targetproc)) {
1231 error = EPERM;
1232 goto out;
1233 }
1234 }
1235
1236 if (pid == -2) {
1237 vm_pageout_anonymous_pages();
1238 } else if (pid == -1) {
1239 memorystatus_on_inactivity(targetproc);
1240 } else {
1241 error = memorystatus_freeze_process_sync(targetproc);
1242 }
1243
1244 out:
1245
1246 #endif /* CONFIG_FREEZE */
1247
1248 if (targetproc != PROC_NULL)
1249 proc_rele(targetproc);
1250 *ret = error;
1251 return error;
1252 }
1253 #endif /* CONFIG_EMBEDDED */
1254
1255 #if SOCKETS
1256 int
1257 networking_memstatus_callout(proc_t p, uint32_t status)
1258 {
1259 struct filedesc *fdp;
1260 int i;
1261
1262 /*
1263 * proc list lock NOT held
1264 * proc lock NOT held
1265 * a reference on the proc has been held / shall be dropped by the caller.
1266 */
1267 LCK_MTX_ASSERT(proc_list_mlock, LCK_MTX_ASSERT_NOTOWNED);
1268 LCK_MTX_ASSERT(&p->p_mlock, LCK_MTX_ASSERT_NOTOWNED);
1269
1270 proc_fdlock(p);
1271 fdp = p->p_fd;
1272 for (i = 0; i < fdp->fd_nfiles; i++) {
1273 struct fileproc *fp;
1274
1275 fp = fdp->fd_ofiles[i];
1276 if (fp == NULL || (fdp->fd_ofileflags[i] & UF_RESERVED) != 0) {
1277 continue;
1278 }
1279 switch (FILEGLOB_DTYPE(fp->f_fglob)) {
1280 #if NECP
1281 case DTYPE_NETPOLICY:
1282 necp_fd_memstatus(p, status,
1283 (struct necp_fd_data *)fp->f_fglob->fg_data);
1284 break;
1285 #endif /* NECP */
1286 default:
1287 break;
1288 }
1289 }
1290 proc_fdunlock(p);
1291
1292 return (1);
1293 }
1294
1295
1296 static int
1297 networking_defunct_callout(proc_t p, void *arg)
1298 {
1299 struct pid_shutdown_sockets_args *args = arg;
1300 int pid = args->pid;
1301 int level = args->level;
1302 struct filedesc *fdp;
1303 int i;
1304
1305 proc_fdlock(p);
1306 fdp = p->p_fd;
1307 for (i = 0; i < fdp->fd_nfiles; i++) {
1308 struct fileproc *fp = fdp->fd_ofiles[i];
1309 struct fileglob *fg;
1310
1311 if (fp == NULL || (fdp->fd_ofileflags[i] & UF_RESERVED) != 0) {
1312 continue;
1313 }
1314
1315 fg = fp->f_fglob;
1316 switch (FILEGLOB_DTYPE(fg)) {
1317 case DTYPE_SOCKET: {
1318 struct socket *so = (struct socket *)fg->fg_data;
1319 if (p->p_pid == pid || so->last_pid == pid ||
1320 ((so->so_flags & SOF_DELEGATED) && so->e_pid == pid)) {
1321 /* Call networking stack with socket and level */
1322 (void) socket_defunct(p, so, level);
1323 }
1324 break;
1325 }
1326 #if NECP
1327 case DTYPE_NETPOLICY:
1328 /* first pass: defunct necp and get stats for ntstat */
1329 if (p->p_pid == pid) {
1330 necp_fd_defunct(p,
1331 (struct necp_fd_data *)fg->fg_data);
1332 }
1333 break;
1334 #endif /* NECP */
1335 default:
1336 break;
1337 }
1338 }
1339
1340 proc_fdunlock(p);
1341
1342 return (PROC_RETURNED);
1343 }
1344
1345 int
1346 pid_shutdown_sockets(struct proc *p __unused, struct pid_shutdown_sockets_args *args, int *ret)
1347 {
1348 int error = 0;
1349 proc_t targetproc = PROC_NULL;
1350 int pid = args->pid;
1351 int level = args->level;
1352
1353 if (level != SHUTDOWN_SOCKET_LEVEL_DISCONNECT_SVC &&
1354 level != SHUTDOWN_SOCKET_LEVEL_DISCONNECT_ALL) {
1355 error = EINVAL;
1356 goto out;
1357 }
1358
1359 #if CONFIG_MACF
1360 error = mac_proc_check_suspend_resume(p, MAC_PROC_CHECK_SHUTDOWN_SOCKETS);
1361 if (error) {
1362 error = EPERM;
1363 goto out;
1364 }
1365 #endif
1366
1367 targetproc = proc_find(pid);
1368 if (targetproc == PROC_NULL) {
1369 error = ESRCH;
1370 goto out;
1371 }
1372
1373 if (!task_for_pid_posix_check(targetproc)) {
1374 error = EPERM;
1375 goto out;
1376 }
1377
1378 proc_iterate(PROC_ALLPROCLIST | PROC_NOWAITTRANS,
1379 networking_defunct_callout, args, NULL, NULL);
1380
1381 out:
1382 if (targetproc != PROC_NULL)
1383 proc_rele(targetproc);
1384 *ret = error;
1385 return error;
1386 }
1387
1388 #endif /* SOCKETS */
1389
1390 static int
1391 sysctl_settfp_policy(__unused struct sysctl_oid *oidp, void *arg1,
1392 __unused int arg2, struct sysctl_req *req)
1393 {
1394 int error = 0;
1395 int new_value;
1396
1397 error = SYSCTL_OUT(req, arg1, sizeof(int));
1398 if (error || req->newptr == USER_ADDR_NULL)
1399 return(error);
1400
1401 if (!kauth_cred_issuser(kauth_cred_get()))
1402 return(EPERM);
1403
1404 if ((error = SYSCTL_IN(req, &new_value, sizeof(int)))) {
1405 goto out;
1406 }
1407 if ((new_value == KERN_TFP_POLICY_DENY)
1408 || (new_value == KERN_TFP_POLICY_DEFAULT))
1409 tfp_policy = new_value;
1410 else
1411 error = EINVAL;
1412 out:
1413 return(error);
1414
1415 }
1416
1417 #if defined(SECURE_KERNEL)
1418 static int kern_secure_kernel = 1;
1419 #else
1420 static int kern_secure_kernel = 0;
1421 #endif
1422
1423 SYSCTL_INT(_kern, OID_AUTO, secure_kernel, CTLFLAG_RD | CTLFLAG_LOCKED, &kern_secure_kernel, 0, "");
1424
1425 SYSCTL_NODE(_kern, KERN_TFP, tfp, CTLFLAG_RW | CTLFLAG_LOCKED, 0, "tfp");
1426 SYSCTL_PROC(_kern_tfp, KERN_TFP_POLICY, policy, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
1427 &tfp_policy, sizeof(uint32_t), &sysctl_settfp_policy ,"I","policy");
1428
1429 SYSCTL_INT(_vm, OID_AUTO, shared_region_trace_level, CTLFLAG_RW | CTLFLAG_LOCKED,
1430 &shared_region_trace_level, 0, "");
1431 SYSCTL_INT(_vm, OID_AUTO, shared_region_version, CTLFLAG_RD | CTLFLAG_LOCKED,
1432 &shared_region_version, 0, "");
1433 SYSCTL_INT(_vm, OID_AUTO, shared_region_persistence, CTLFLAG_RW | CTLFLAG_LOCKED,
1434 &shared_region_persistence, 0, "");
1435
1436 /*
1437 * shared_region_check_np:
1438 *
1439 * This system call is intended for dyld.
1440 *
1441 * dyld calls this when any process starts to see if the process's shared
1442 * region is already set up and ready to use.
1443 * This call returns the base address of the first mapping in the
1444 * process's shared region's first mapping.
1445 * dyld will then check what's mapped at that address.
1446 *
1447 * If the shared region is empty, dyld will then attempt to map the shared
1448 * cache file in the shared region via the shared_region_map_np() system call.
1449 *
1450 * If something's already mapped in the shared region, dyld will check if it
1451 * matches the shared cache it would like to use for that process.
1452 * If it matches, evrything's ready and the process can proceed and use the
1453 * shared region.
1454 * If it doesn't match, dyld will unmap the shared region and map the shared
1455 * cache into the process's address space via mmap().
1456 *
1457 * ERROR VALUES
1458 * EINVAL no shared region
1459 * ENOMEM shared region is empty
1460 * EFAULT bad address for "start_address"
1461 */
1462 int
1463 shared_region_check_np(
1464 __unused struct proc *p,
1465 struct shared_region_check_np_args *uap,
1466 __unused int *retvalp)
1467 {
1468 vm_shared_region_t shared_region;
1469 mach_vm_offset_t start_address = 0;
1470 int error;
1471 kern_return_t kr;
1472
1473 SHARED_REGION_TRACE_DEBUG(
1474 ("shared_region: %p [%d(%s)] -> check_np(0x%llx)\n",
1475 (void *)VM_KERNEL_ADDRPERM(current_thread()),
1476 p->p_pid, p->p_comm,
1477 (uint64_t)uap->start_address));
1478
1479 /* retrieve the current tasks's shared region */
1480 shared_region = vm_shared_region_get(current_task());
1481 if (shared_region != NULL) {
1482 /* retrieve address of its first mapping... */
1483 kr = vm_shared_region_start_address(shared_region,
1484 &start_address);
1485 if (kr != KERN_SUCCESS) {
1486 error = ENOMEM;
1487 } else {
1488 /* ... and give it to the caller */
1489 error = copyout(&start_address,
1490 (user_addr_t) uap->start_address,
1491 sizeof (start_address));
1492 if (error) {
1493 SHARED_REGION_TRACE_ERROR(
1494 ("shared_region: %p [%d(%s)] "
1495 "check_np(0x%llx) "
1496 "copyout(0x%llx) error %d\n",
1497 (void *)VM_KERNEL_ADDRPERM(current_thread()),
1498 p->p_pid, p->p_comm,
1499 (uint64_t)uap->start_address, (uint64_t)start_address,
1500 error));
1501 }
1502 }
1503 vm_shared_region_deallocate(shared_region);
1504 } else {
1505 /* no shared region ! */
1506 error = EINVAL;
1507 }
1508
1509 SHARED_REGION_TRACE_DEBUG(
1510 ("shared_region: %p [%d(%s)] check_np(0x%llx) <- 0x%llx %d\n",
1511 (void *)VM_KERNEL_ADDRPERM(current_thread()),
1512 p->p_pid, p->p_comm,
1513 (uint64_t)uap->start_address, (uint64_t)start_address, error));
1514
1515 return error;
1516 }
1517
1518
1519 int
1520 shared_region_copyin_mappings(
1521 struct proc *p,
1522 user_addr_t user_mappings,
1523 unsigned int mappings_count,
1524 struct shared_file_mapping_np *mappings)
1525 {
1526 int error = 0;
1527 vm_size_t mappings_size = 0;
1528
1529 /* get the list of mappings the caller wants us to establish */
1530 mappings_size = (vm_size_t) (mappings_count * sizeof (mappings[0]));
1531 error = copyin(user_mappings,
1532 mappings,
1533 mappings_size);
1534 if (error) {
1535 SHARED_REGION_TRACE_ERROR(
1536 ("shared_region: %p [%d(%s)] map(): "
1537 "copyin(0x%llx, %d) failed (error=%d)\n",
1538 (void *)VM_KERNEL_ADDRPERM(current_thread()),
1539 p->p_pid, p->p_comm,
1540 (uint64_t)user_mappings, mappings_count, error));
1541 }
1542 return error;
1543 }
1544 /*
1545 * shared_region_map_np()
1546 *
1547 * This system call is intended for dyld.
1548 *
1549 * dyld uses this to map a shared cache file into a shared region.
1550 * This is usually done only the first time a shared cache is needed.
1551 * Subsequent processes will just use the populated shared region without
1552 * requiring any further setup.
1553 */
1554 int
1555 _shared_region_map_and_slide(
1556 struct proc *p,
1557 int fd,
1558 uint32_t mappings_count,
1559 struct shared_file_mapping_np *mappings,
1560 uint32_t slide,
1561 user_addr_t slide_start,
1562 user_addr_t slide_size)
1563 {
1564 int error;
1565 kern_return_t kr;
1566 struct fileproc *fp;
1567 struct vnode *vp, *root_vp, *scdir_vp;
1568 struct vnode_attr va;
1569 off_t fs;
1570 memory_object_size_t file_size;
1571 #if CONFIG_MACF
1572 vm_prot_t maxprot = VM_PROT_ALL;
1573 #endif
1574 memory_object_control_t file_control;
1575 struct vm_shared_region *shared_region;
1576 uint32_t i;
1577
1578 SHARED_REGION_TRACE_DEBUG(
1579 ("shared_region: %p [%d(%s)] -> map\n",
1580 (void *)VM_KERNEL_ADDRPERM(current_thread()),
1581 p->p_pid, p->p_comm));
1582
1583 shared_region = NULL;
1584 fp = NULL;
1585 vp = NULL;
1586 scdir_vp = NULL;
1587
1588 /* get file structure from file descriptor */
1589 error = fp_lookup(p, fd, &fp, 0);
1590 if (error) {
1591 SHARED_REGION_TRACE_ERROR(
1592 ("shared_region: %p [%d(%s)] map: "
1593 "fd=%d lookup failed (error=%d)\n",
1594 (void *)VM_KERNEL_ADDRPERM(current_thread()),
1595 p->p_pid, p->p_comm, fd, error));
1596 goto done;
1597 }
1598
1599 /* make sure we're attempting to map a vnode */
1600 if (FILEGLOB_DTYPE(fp->f_fglob) != DTYPE_VNODE) {
1601 SHARED_REGION_TRACE_ERROR(
1602 ("shared_region: %p [%d(%s)] map: "
1603 "fd=%d not a vnode (type=%d)\n",
1604 (void *)VM_KERNEL_ADDRPERM(current_thread()),
1605 p->p_pid, p->p_comm,
1606 fd, FILEGLOB_DTYPE(fp->f_fglob)));
1607 error = EINVAL;
1608 goto done;
1609 }
1610
1611 /* we need at least read permission on the file */
1612 if (! (fp->f_fglob->fg_flag & FREAD)) {
1613 SHARED_REGION_TRACE_ERROR(
1614 ("shared_region: %p [%d(%s)] map: "
1615 "fd=%d not readable\n",
1616 (void *)VM_KERNEL_ADDRPERM(current_thread()),
1617 p->p_pid, p->p_comm, fd));
1618 error = EPERM;
1619 goto done;
1620 }
1621
1622 /* get vnode from file structure */
1623 error = vnode_getwithref((vnode_t) fp->f_fglob->fg_data);
1624 if (error) {
1625 SHARED_REGION_TRACE_ERROR(
1626 ("shared_region: %p [%d(%s)] map: "
1627 "fd=%d getwithref failed (error=%d)\n",
1628 (void *)VM_KERNEL_ADDRPERM(current_thread()),
1629 p->p_pid, p->p_comm, fd, error));
1630 goto done;
1631 }
1632 vp = (struct vnode *) fp->f_fglob->fg_data;
1633
1634 /* make sure the vnode is a regular file */
1635 if (vp->v_type != VREG) {
1636 SHARED_REGION_TRACE_ERROR(
1637 ("shared_region: %p [%d(%s)] map(%p:'%s'): "
1638 "not a file (type=%d)\n",
1639 (void *)VM_KERNEL_ADDRPERM(current_thread()),
1640 p->p_pid, p->p_comm,
1641 (void *)VM_KERNEL_ADDRPERM(vp),
1642 vp->v_name, vp->v_type));
1643 error = EINVAL;
1644 goto done;
1645 }
1646
1647 #if CONFIG_MACF
1648 /* pass in 0 for the offset argument because AMFI does not need the offset
1649 of the shared cache */
1650 error = mac_file_check_mmap(vfs_context_ucred(vfs_context_current()),
1651 fp->f_fglob, VM_PROT_ALL, MAP_FILE, 0, &maxprot);
1652 if (error) {
1653 goto done;
1654 }
1655 #endif /* MAC */
1656
1657 /* make sure vnode is on the process's root volume */
1658 root_vp = p->p_fd->fd_rdir;
1659 if (root_vp == NULL) {
1660 root_vp = rootvnode;
1661 } else {
1662 /*
1663 * Chroot-ed processes can't use the shared_region.
1664 */
1665 error = EINVAL;
1666 goto done;
1667 }
1668
1669 if (vp->v_mount != root_vp->v_mount) {
1670 SHARED_REGION_TRACE_ERROR(
1671 ("shared_region: %p [%d(%s)] map(%p:'%s'): "
1672 "not on process's root volume\n",
1673 (void *)VM_KERNEL_ADDRPERM(current_thread()),
1674 p->p_pid, p->p_comm,
1675 (void *)VM_KERNEL_ADDRPERM(vp), vp->v_name));
1676 error = EPERM;
1677 goto done;
1678 }
1679
1680 /* make sure vnode is owned by "root" */
1681 VATTR_INIT(&va);
1682 VATTR_WANTED(&va, va_uid);
1683 error = vnode_getattr(vp, &va, vfs_context_current());
1684 if (error) {
1685 SHARED_REGION_TRACE_ERROR(
1686 ("shared_region: %p [%d(%s)] map(%p:'%s'): "
1687 "vnode_getattr(%p) failed (error=%d)\n",
1688 (void *)VM_KERNEL_ADDRPERM(current_thread()),
1689 p->p_pid, p->p_comm,
1690 (void *)VM_KERNEL_ADDRPERM(vp), vp->v_name,
1691 (void *)VM_KERNEL_ADDRPERM(vp), error));
1692 goto done;
1693 }
1694 if (va.va_uid != 0) {
1695 SHARED_REGION_TRACE_ERROR(
1696 ("shared_region: %p [%d(%s)] map(%p:'%s'): "
1697 "owned by uid=%d instead of 0\n",
1698 (void *)VM_KERNEL_ADDRPERM(current_thread()),
1699 p->p_pid, p->p_comm,
1700 (void *)VM_KERNEL_ADDRPERM(vp),
1701 vp->v_name, va.va_uid));
1702 error = EPERM;
1703 goto done;
1704 }
1705
1706 if (scdir_enforce) {
1707 /* get vnode for scdir_path */
1708 error = vnode_lookup(scdir_path, 0, &scdir_vp, vfs_context_current());
1709 if (error) {
1710 SHARED_REGION_TRACE_ERROR(
1711 ("shared_region: %p [%d(%s)] map(%p:'%s'): "
1712 "vnode_lookup(%s) failed (error=%d)\n",
1713 (void *)VM_KERNEL_ADDRPERM(current_thread()),
1714 p->p_pid, p->p_comm,
1715 (void *)VM_KERNEL_ADDRPERM(vp), vp->v_name,
1716 scdir_path, error));
1717 goto done;
1718 }
1719
1720 /* ensure parent is scdir_vp */
1721 if (vnode_parent(vp) != scdir_vp) {
1722 SHARED_REGION_TRACE_ERROR(
1723 ("shared_region: %p [%d(%s)] map(%p:'%s'): "
1724 "shared cache file not in %s\n",
1725 (void *)VM_KERNEL_ADDRPERM(current_thread()),
1726 p->p_pid, p->p_comm,
1727 (void *)VM_KERNEL_ADDRPERM(vp),
1728 vp->v_name, scdir_path));
1729 error = EPERM;
1730 goto done;
1731 }
1732 }
1733
1734 /* get vnode size */
1735 error = vnode_size(vp, &fs, vfs_context_current());
1736 if (error) {
1737 SHARED_REGION_TRACE_ERROR(
1738 ("shared_region: %p [%d(%s)] map(%p:'%s'): "
1739 "vnode_size(%p) failed (error=%d)\n",
1740 (void *)VM_KERNEL_ADDRPERM(current_thread()),
1741 p->p_pid, p->p_comm,
1742 (void *)VM_KERNEL_ADDRPERM(vp), vp->v_name,
1743 (void *)VM_KERNEL_ADDRPERM(vp), error));
1744 goto done;
1745 }
1746 file_size = fs;
1747
1748 /* get the file's memory object handle */
1749 file_control = ubc_getobject(vp, UBC_HOLDOBJECT);
1750 if (file_control == MEMORY_OBJECT_CONTROL_NULL) {
1751 SHARED_REGION_TRACE_ERROR(
1752 ("shared_region: %p [%d(%s)] map(%p:'%s'): "
1753 "no memory object\n",
1754 (void *)VM_KERNEL_ADDRPERM(current_thread()),
1755 p->p_pid, p->p_comm,
1756 (void *)VM_KERNEL_ADDRPERM(vp), vp->v_name));
1757 error = EINVAL;
1758 goto done;
1759 }
1760
1761 /* check that the mappings are properly covered by code signatures */
1762 if (!cs_enforcement(NULL)) {
1763 /* code signing is not enforced: no need to check */
1764 } else for (i = 0; i < mappings_count; i++) {
1765 if (mappings[i].sfm_init_prot & VM_PROT_ZF) {
1766 /* zero-filled mapping: not backed by the file */
1767 continue;
1768 }
1769 if (ubc_cs_is_range_codesigned(vp,
1770 mappings[i].sfm_file_offset,
1771 mappings[i].sfm_size)) {
1772 /* this mapping is fully covered by code signatures */
1773 continue;
1774 }
1775 SHARED_REGION_TRACE_ERROR(
1776 ("shared_region: %p [%d(%s)] map(%p:'%s'): "
1777 "mapping #%d/%d [0x%llx:0x%llx:0x%llx:0x%x:0x%x] "
1778 "is not code-signed\n",
1779 (void *)VM_KERNEL_ADDRPERM(current_thread()),
1780 p->p_pid, p->p_comm,
1781 (void *)VM_KERNEL_ADDRPERM(vp), vp->v_name,
1782 i, mappings_count,
1783 mappings[i].sfm_address,
1784 mappings[i].sfm_size,
1785 mappings[i].sfm_file_offset,
1786 mappings[i].sfm_max_prot,
1787 mappings[i].sfm_init_prot));
1788 error = EINVAL;
1789 goto done;
1790 }
1791
1792 /* get the process's shared region (setup in vm_map_exec()) */
1793 shared_region = vm_shared_region_get(current_task());
1794 if (shared_region == NULL) {
1795 SHARED_REGION_TRACE_ERROR(
1796 ("shared_region: %p [%d(%s)] map(%p:'%s'): "
1797 "no shared region\n",
1798 (void *)VM_KERNEL_ADDRPERM(current_thread()),
1799 p->p_pid, p->p_comm,
1800 (void *)VM_KERNEL_ADDRPERM(vp), vp->v_name));
1801 goto done;
1802 }
1803
1804 /* map the file into that shared region's submap */
1805 kr = vm_shared_region_map_file(shared_region,
1806 mappings_count,
1807 mappings,
1808 file_control,
1809 file_size,
1810 (void *) p->p_fd->fd_rdir,
1811 slide,
1812 slide_start,
1813 slide_size);
1814 if (kr != KERN_SUCCESS) {
1815 SHARED_REGION_TRACE_ERROR(
1816 ("shared_region: %p [%d(%s)] map(%p:'%s'): "
1817 "vm_shared_region_map_file() failed kr=0x%x\n",
1818 (void *)VM_KERNEL_ADDRPERM(current_thread()),
1819 p->p_pid, p->p_comm,
1820 (void *)VM_KERNEL_ADDRPERM(vp), vp->v_name, kr));
1821 switch (kr) {
1822 case KERN_INVALID_ADDRESS:
1823 error = EFAULT;
1824 break;
1825 case KERN_PROTECTION_FAILURE:
1826 error = EPERM;
1827 break;
1828 case KERN_NO_SPACE:
1829 error = ENOMEM;
1830 break;
1831 case KERN_FAILURE:
1832 case KERN_INVALID_ARGUMENT:
1833 default:
1834 error = EINVAL;
1835 break;
1836 }
1837 goto done;
1838 }
1839
1840 error = 0;
1841
1842 vnode_lock_spin(vp);
1843
1844 vp->v_flag |= VSHARED_DYLD;
1845
1846 vnode_unlock(vp);
1847
1848 /* update the vnode's access time */
1849 if (! (vnode_vfsvisflags(vp) & MNT_NOATIME)) {
1850 VATTR_INIT(&va);
1851 nanotime(&va.va_access_time);
1852 VATTR_SET_ACTIVE(&va, va_access_time);
1853 vnode_setattr(vp, &va, vfs_context_current());
1854 }
1855
1856 if (p->p_flag & P_NOSHLIB) {
1857 /* signal that this process is now using split libraries */
1858 OSBitAndAtomic(~((uint32_t)P_NOSHLIB), &p->p_flag);
1859 }
1860
1861 done:
1862 if (vp != NULL) {
1863 /*
1864 * release the vnode...
1865 * ubc_map() still holds it for us in the non-error case
1866 */
1867 (void) vnode_put(vp);
1868 vp = NULL;
1869 }
1870 if (fp != NULL) {
1871 /* release the file descriptor */
1872 fp_drop(p, fd, fp, 0);
1873 fp = NULL;
1874 }
1875 if (scdir_vp != NULL) {
1876 (void)vnode_put(scdir_vp);
1877 scdir_vp = NULL;
1878 }
1879
1880 if (shared_region != NULL) {
1881 vm_shared_region_deallocate(shared_region);
1882 }
1883
1884 SHARED_REGION_TRACE_DEBUG(
1885 ("shared_region: %p [%d(%s)] <- map\n",
1886 (void *)VM_KERNEL_ADDRPERM(current_thread()),
1887 p->p_pid, p->p_comm));
1888
1889 return error;
1890 }
1891
1892 int
1893 shared_region_map_and_slide_np(
1894 struct proc *p,
1895 struct shared_region_map_and_slide_np_args *uap,
1896 __unused int *retvalp)
1897 {
1898 struct shared_file_mapping_np *mappings;
1899 unsigned int mappings_count = uap->count;
1900 kern_return_t kr = KERN_SUCCESS;
1901 uint32_t slide = uap->slide;
1902
1903 #define SFM_MAX_STACK 8
1904 struct shared_file_mapping_np stack_mappings[SFM_MAX_STACK];
1905
1906 /* Is the process chrooted?? */
1907 if (p->p_fd->fd_rdir != NULL) {
1908 kr = EINVAL;
1909 goto done;
1910 }
1911
1912 if ((kr = vm_shared_region_sliding_valid(slide)) != KERN_SUCCESS) {
1913 if (kr == KERN_INVALID_ARGUMENT) {
1914 /*
1915 * This will happen if we request sliding again
1916 * with the same slide value that was used earlier
1917 * for the very first sliding.
1918 */
1919 kr = KERN_SUCCESS;
1920 }
1921 goto done;
1922 }
1923
1924 if (mappings_count == 0) {
1925 SHARED_REGION_TRACE_INFO(
1926 ("shared_region: %p [%d(%s)] map(): "
1927 "no mappings\n",
1928 (void *)VM_KERNEL_ADDRPERM(current_thread()),
1929 p->p_pid, p->p_comm));
1930 kr = 0; /* no mappings: we're done ! */
1931 goto done;
1932 } else if (mappings_count <= SFM_MAX_STACK) {
1933 mappings = &stack_mappings[0];
1934 } else {
1935 SHARED_REGION_TRACE_ERROR(
1936 ("shared_region: %p [%d(%s)] map(): "
1937 "too many mappings (%d)\n",
1938 (void *)VM_KERNEL_ADDRPERM(current_thread()),
1939 p->p_pid, p->p_comm,
1940 mappings_count));
1941 kr = KERN_FAILURE;
1942 goto done;
1943 }
1944
1945 if ( (kr = shared_region_copyin_mappings(p, uap->mappings, uap->count, mappings))) {
1946 goto done;
1947 }
1948
1949
1950 kr = _shared_region_map_and_slide(p, uap->fd, mappings_count, mappings,
1951 slide,
1952 uap->slide_start, uap->slide_size);
1953 if (kr != KERN_SUCCESS) {
1954 return kr;
1955 }
1956
1957 done:
1958 return kr;
1959 }
1960
1961 /* sysctl overflow room */
1962
1963 SYSCTL_INT (_vm, OID_AUTO, pagesize, CTLFLAG_RD | CTLFLAG_LOCKED,
1964 (int *) &page_size, 0, "vm page size");
1965
1966 /* vm_page_free_target is provided as a makeshift solution for applications that want to
1967 allocate buffer space, possibly purgeable memory, but not cause inactive pages to be
1968 reclaimed. It allows the app to calculate how much memory is free outside the free target. */
1969 extern unsigned int vm_page_free_target;
1970 SYSCTL_INT(_vm, OID_AUTO, vm_page_free_target, CTLFLAG_RD | CTLFLAG_LOCKED,
1971 &vm_page_free_target, 0, "Pageout daemon free target");
1972
1973 extern unsigned int vm_memory_pressure;
1974 SYSCTL_INT(_vm, OID_AUTO, memory_pressure, CTLFLAG_RD | CTLFLAG_LOCKED,
1975 &vm_memory_pressure, 0, "Memory pressure indicator");
1976
1977 static int
1978 vm_ctl_page_free_wanted SYSCTL_HANDLER_ARGS
1979 {
1980 #pragma unused(oidp, arg1, arg2)
1981 unsigned int page_free_wanted;
1982
1983 page_free_wanted = mach_vm_ctl_page_free_wanted();
1984 return SYSCTL_OUT(req, &page_free_wanted, sizeof (page_free_wanted));
1985 }
1986 SYSCTL_PROC(_vm, OID_AUTO, page_free_wanted,
1987 CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
1988 0, 0, vm_ctl_page_free_wanted, "I", "");
1989
1990 extern unsigned int vm_page_purgeable_count;
1991 SYSCTL_INT(_vm, OID_AUTO, page_purgeable_count, CTLFLAG_RD | CTLFLAG_LOCKED,
1992 &vm_page_purgeable_count, 0, "Purgeable page count");
1993
1994 extern unsigned int vm_page_purgeable_wired_count;
1995 SYSCTL_INT(_vm, OID_AUTO, page_purgeable_wired_count, CTLFLAG_RD | CTLFLAG_LOCKED,
1996 &vm_page_purgeable_wired_count, 0, "Wired purgeable page count");
1997
1998 extern unsigned int vm_pageout_purged_objects;
1999 SYSCTL_INT(_vm, OID_AUTO, pageout_purged_objects, CTLFLAG_RD | CTLFLAG_LOCKED,
2000 &vm_pageout_purged_objects, 0, "System purged object count");
2001
2002 extern int madvise_free_debug;
2003 SYSCTL_INT(_vm, OID_AUTO, madvise_free_debug, CTLFLAG_RW | CTLFLAG_LOCKED,
2004 &madvise_free_debug, 0, "zero-fill on madvise(MADV_FREE*)");
2005
2006 SYSCTL_INT(_vm, OID_AUTO, page_reusable_count, CTLFLAG_RD | CTLFLAG_LOCKED,
2007 &vm_page_stats_reusable.reusable_count, 0, "Reusable page count");
2008 SYSCTL_QUAD(_vm, OID_AUTO, reusable_success, CTLFLAG_RD | CTLFLAG_LOCKED,
2009 &vm_page_stats_reusable.reusable_pages_success, "");
2010 SYSCTL_QUAD(_vm, OID_AUTO, reusable_failure, CTLFLAG_RD | CTLFLAG_LOCKED,
2011 &vm_page_stats_reusable.reusable_pages_failure, "");
2012 SYSCTL_QUAD(_vm, OID_AUTO, reusable_pages_shared, CTLFLAG_RD | CTLFLAG_LOCKED,
2013 &vm_page_stats_reusable.reusable_pages_shared, "");
2014 SYSCTL_QUAD(_vm, OID_AUTO, all_reusable_calls, CTLFLAG_RD | CTLFLAG_LOCKED,
2015 &vm_page_stats_reusable.all_reusable_calls, "");
2016 SYSCTL_QUAD(_vm, OID_AUTO, partial_reusable_calls, CTLFLAG_RD | CTLFLAG_LOCKED,
2017 &vm_page_stats_reusable.partial_reusable_calls, "");
2018 SYSCTL_QUAD(_vm, OID_AUTO, reuse_success, CTLFLAG_RD | CTLFLAG_LOCKED,
2019 &vm_page_stats_reusable.reuse_pages_success, "");
2020 SYSCTL_QUAD(_vm, OID_AUTO, reuse_failure, CTLFLAG_RD | CTLFLAG_LOCKED,
2021 &vm_page_stats_reusable.reuse_pages_failure, "");
2022 SYSCTL_QUAD(_vm, OID_AUTO, all_reuse_calls, CTLFLAG_RD | CTLFLAG_LOCKED,
2023 &vm_page_stats_reusable.all_reuse_calls, "");
2024 SYSCTL_QUAD(_vm, OID_AUTO, partial_reuse_calls, CTLFLAG_RD | CTLFLAG_LOCKED,
2025 &vm_page_stats_reusable.partial_reuse_calls, "");
2026 SYSCTL_QUAD(_vm, OID_AUTO, can_reuse_success, CTLFLAG_RD | CTLFLAG_LOCKED,
2027 &vm_page_stats_reusable.can_reuse_success, "");
2028 SYSCTL_QUAD(_vm, OID_AUTO, can_reuse_failure, CTLFLAG_RD | CTLFLAG_LOCKED,
2029 &vm_page_stats_reusable.can_reuse_failure, "");
2030 SYSCTL_QUAD(_vm, OID_AUTO, reusable_reclaimed, CTLFLAG_RD | CTLFLAG_LOCKED,
2031 &vm_page_stats_reusable.reusable_reclaimed, "");
2032 SYSCTL_QUAD(_vm, OID_AUTO, reusable_nonwritable, CTLFLAG_RD | CTLFLAG_LOCKED,
2033 &vm_page_stats_reusable.reusable_nonwritable, "");
2034 SYSCTL_QUAD(_vm, OID_AUTO, reusable_shared, CTLFLAG_RD | CTLFLAG_LOCKED,
2035 &vm_page_stats_reusable.reusable_shared, "");
2036 SYSCTL_QUAD(_vm, OID_AUTO, free_shared, CTLFLAG_RD | CTLFLAG_LOCKED,
2037 &vm_page_stats_reusable.free_shared, "");
2038
2039
2040 extern unsigned int vm_page_free_count, vm_page_speculative_count;
2041 SYSCTL_UINT(_vm, OID_AUTO, page_free_count, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_page_free_count, 0, "");
2042 SYSCTL_UINT(_vm, OID_AUTO, page_speculative_count, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_page_speculative_count, 0, "");
2043
2044 extern unsigned int vm_page_cleaned_count;
2045 SYSCTL_UINT(_vm, OID_AUTO, page_cleaned_count, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_page_cleaned_count, 0, "Cleaned queue size");
2046
2047 extern unsigned int vm_page_pageable_internal_count, vm_page_pageable_external_count;
2048 SYSCTL_UINT(_vm, OID_AUTO, page_pageable_internal_count, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_page_pageable_internal_count, 0, "");
2049 SYSCTL_UINT(_vm, OID_AUTO, page_pageable_external_count, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_page_pageable_external_count, 0, "");
2050
2051 /* pageout counts */
2052 extern unsigned int vm_pageout_inactive_dirty_internal, vm_pageout_inactive_dirty_external, vm_pageout_inactive_clean, vm_pageout_speculative_clean, vm_pageout_inactive_used;
2053 extern unsigned int vm_pageout_freed_from_inactive_clean, vm_pageout_freed_from_speculative;
2054 SYSCTL_UINT(_vm, OID_AUTO, pageout_inactive_dirty_internal, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_pageout_inactive_dirty_internal, 0, "");
2055 SYSCTL_UINT(_vm, OID_AUTO, pageout_inactive_dirty_external, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_pageout_inactive_dirty_external, 0, "");
2056 SYSCTL_UINT(_vm, OID_AUTO, pageout_inactive_clean, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_pageout_inactive_clean, 0, "");
2057 SYSCTL_UINT(_vm, OID_AUTO, pageout_speculative_clean, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_pageout_speculative_clean, 0, "");
2058 SYSCTL_UINT(_vm, OID_AUTO, pageout_inactive_used, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_pageout_inactive_used, 0, "");
2059 SYSCTL_UINT(_vm, OID_AUTO, pageout_freed_from_inactive_clean, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_pageout_freed_from_inactive_clean, 0, "");
2060 SYSCTL_UINT(_vm, OID_AUTO, pageout_freed_from_speculative, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_pageout_freed_from_speculative, 0, "");
2061
2062 extern unsigned int vm_pageout_freed_from_cleaned;
2063 SYSCTL_UINT(_vm, OID_AUTO, pageout_freed_from_cleaned, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_pageout_freed_from_cleaned, 0, "");
2064
2065 /* counts of pages entering the cleaned queue */
2066 extern unsigned int vm_pageout_enqueued_cleaned, vm_pageout_enqueued_cleaned_from_inactive_dirty;
2067 SYSCTL_UINT(_vm, OID_AUTO, pageout_enqueued_cleaned, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_pageout_enqueued_cleaned, 0, ""); /* sum of next two */
2068 SYSCTL_UINT(_vm, OID_AUTO, pageout_enqueued_cleaned_from_inactive_dirty, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_pageout_enqueued_cleaned_from_inactive_dirty, 0, "");
2069
2070 /* counts of pages leaving the cleaned queue */
2071 extern unsigned int vm_pageout_cleaned_reclaimed, vm_pageout_cleaned_reactivated, vm_pageout_cleaned_reference_reactivated, vm_pageout_cleaned_volatile_reactivated, vm_pageout_cleaned_fault_reactivated, vm_pageout_cleaned_commit_reactivated, vm_pageout_cleaned_busy, vm_pageout_cleaned_nolock;
2072 SYSCTL_UINT(_vm, OID_AUTO, pageout_cleaned, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_pageout_cleaned_reclaimed, 0, "Cleaned pages reclaimed");
2073 SYSCTL_UINT(_vm, OID_AUTO, pageout_cleaned_reactivated, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_pageout_cleaned_reactivated, 0, "Cleaned pages reactivated"); /* sum of all reactivated AND busy and nolock (even though those actually get reDEactivated */
2074 SYSCTL_UINT(_vm, OID_AUTO, pageout_cleaned_reference_reactivated, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_pageout_cleaned_reference_reactivated, 0, "Cleaned pages reference reactivated");
2075 SYSCTL_UINT(_vm, OID_AUTO, pageout_cleaned_volatile_reactivated, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_pageout_cleaned_volatile_reactivated, 0, "Cleaned pages volatile reactivated");
2076 SYSCTL_UINT(_vm, OID_AUTO, pageout_cleaned_fault_reactivated, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_pageout_cleaned_fault_reactivated, 0, "Cleaned pages fault reactivated");
2077 SYSCTL_UINT(_vm, OID_AUTO, pageout_cleaned_commit_reactivated, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_pageout_cleaned_commit_reactivated, 0, "Cleaned pages commit reactivated");
2078 SYSCTL_UINT(_vm, OID_AUTO, pageout_cleaned_busy, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_pageout_cleaned_busy, 0, "Cleaned pages busy (deactivated)");
2079 SYSCTL_UINT(_vm, OID_AUTO, pageout_cleaned_nolock, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_pageout_cleaned_nolock, 0, "Cleaned pages no-lock (deactivated)");
2080
2081 /* counts of pages prefaulted when entering a memory object */
2082 extern int64_t vm_prefault_nb_pages, vm_prefault_nb_bailout;
2083 SYSCTL_QUAD(_vm, OID_AUTO, prefault_nb_pages, CTLFLAG_RW | CTLFLAG_LOCKED, &vm_prefault_nb_pages, "");
2084 SYSCTL_QUAD(_vm, OID_AUTO, prefault_nb_bailout, CTLFLAG_RW | CTLFLAG_LOCKED, &vm_prefault_nb_bailout, "");
2085
2086 #if defined (__x86_64__)
2087 extern unsigned int vm_clump_promote_threshold;
2088 SYSCTL_UINT(_vm, OID_AUTO, vm_clump_promote_threshold, CTLFLAG_RW | CTLFLAG_LOCKED, &vm_clump_promote_threshold, 0, "clump size threshold for promotes");
2089 #if DEVELOPMENT || DEBUG
2090 extern unsigned long vm_clump_stats[];
2091 SYSCTL_LONG(_vm, OID_AUTO, vm_clump_stats1, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_clump_stats[1], "free page allocations from clump of 1 page");
2092 SYSCTL_LONG(_vm, OID_AUTO, vm_clump_stats2, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_clump_stats[2], "free page allocations from clump of 2 pages");
2093 SYSCTL_LONG(_vm, OID_AUTO, vm_clump_stats3, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_clump_stats[3], "free page allocations from clump of 3 pages");
2094 SYSCTL_LONG(_vm, OID_AUTO, vm_clump_stats4, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_clump_stats[4], "free page allocations from clump of 4 pages");
2095 SYSCTL_LONG(_vm, OID_AUTO, vm_clump_stats5, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_clump_stats[5], "free page allocations from clump of 5 pages");
2096 SYSCTL_LONG(_vm, OID_AUTO, vm_clump_stats6, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_clump_stats[6], "free page allocations from clump of 6 pages");
2097 SYSCTL_LONG(_vm, OID_AUTO, vm_clump_stats7, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_clump_stats[7], "free page allocations from clump of 7 pages");
2098 SYSCTL_LONG(_vm, OID_AUTO, vm_clump_stats8, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_clump_stats[8], "free page allocations from clump of 8 pages");
2099 SYSCTL_LONG(_vm, OID_AUTO, vm_clump_stats9, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_clump_stats[9], "free page allocations from clump of 9 pages");
2100 SYSCTL_LONG(_vm, OID_AUTO, vm_clump_stats10, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_clump_stats[10], "free page allocations from clump of 10 pages");
2101 SYSCTL_LONG(_vm, OID_AUTO, vm_clump_stats11, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_clump_stats[11], "free page allocations from clump of 11 pages");
2102 SYSCTL_LONG(_vm, OID_AUTO, vm_clump_stats12, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_clump_stats[12], "free page allocations from clump of 12 pages");
2103 SYSCTL_LONG(_vm, OID_AUTO, vm_clump_stats13, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_clump_stats[13], "free page allocations from clump of 13 pages");
2104 SYSCTL_LONG(_vm, OID_AUTO, vm_clump_stats14, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_clump_stats[14], "free page allocations from clump of 14 pages");
2105 SYSCTL_LONG(_vm, OID_AUTO, vm_clump_stats15, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_clump_stats[15], "free page allocations from clump of 15 pages");
2106 SYSCTL_LONG(_vm, OID_AUTO, vm_clump_stats16, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_clump_stats[16], "free page allocations from clump of 16 pages");
2107 extern unsigned long vm_clump_allocs, vm_clump_inserts, vm_clump_inrange, vm_clump_promotes;
2108 SYSCTL_LONG(_vm, OID_AUTO, vm_clump_alloc, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_clump_allocs, "free page allocations");
2109 SYSCTL_LONG(_vm, OID_AUTO, vm_clump_inserts, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_clump_inserts, "free page insertions");
2110 SYSCTL_LONG(_vm, OID_AUTO, vm_clump_inrange, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_clump_inrange, "free page insertions that are part of vm_pages");
2111 SYSCTL_LONG(_vm, OID_AUTO, vm_clump_promotes, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_clump_promotes, "pages promoted to head");
2112 #endif /* if DEVELOPMENT || DEBUG */
2113 #endif /* #if defined (__x86_64__) */
2114
2115 #if CONFIG_SECLUDED_MEMORY
2116
2117 SYSCTL_UINT(_vm, OID_AUTO, num_tasks_can_use_secluded_mem, CTLFLAG_RD | CTLFLAG_LOCKED, &num_tasks_can_use_secluded_mem, 0, "");
2118 extern unsigned int vm_page_secluded_target;
2119 extern unsigned int vm_page_secluded_count;
2120 extern unsigned int vm_page_secluded_count_free;
2121 extern unsigned int vm_page_secluded_count_inuse;
2122 SYSCTL_UINT(_vm, OID_AUTO, page_secluded_target, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_page_secluded_target, 0, "");
2123 SYSCTL_UINT(_vm, OID_AUTO, page_secluded_count, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_page_secluded_count, 0, "");
2124 SYSCTL_UINT(_vm, OID_AUTO, page_secluded_count_free, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_page_secluded_count_free, 0, "");
2125 SYSCTL_UINT(_vm, OID_AUTO, page_secluded_count_inuse, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_page_secluded_count_inuse, 0, "");
2126
2127 extern struct vm_page_secluded_data vm_page_secluded;
2128 SYSCTL_UINT(_vm, OID_AUTO, page_secluded_eligible, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_page_secluded.eligible_for_secluded, 0, "");
2129 SYSCTL_UINT(_vm, OID_AUTO, page_secluded_grab_success_free, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_page_secluded.grab_success_free, 0, "");
2130 SYSCTL_UINT(_vm, OID_AUTO, page_secluded_grab_success_other, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_page_secluded.grab_success_other, 0, "");
2131 SYSCTL_UINT(_vm, OID_AUTO, page_secluded_grab_failure_locked, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_page_secluded.grab_failure_locked, 0, "");
2132 SYSCTL_UINT(_vm, OID_AUTO, page_secluded_grab_failure_state, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_page_secluded.grab_failure_state, 0, "");
2133 SYSCTL_UINT(_vm, OID_AUTO, page_secluded_grab_failure_dirty, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_page_secluded.grab_failure_dirty, 0, "");
2134 SYSCTL_UINT(_vm, OID_AUTO, page_secluded_grab_for_iokit, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_page_secluded.grab_for_iokit, 0, "");
2135 SYSCTL_UINT(_vm, OID_AUTO, page_secluded_grab_for_iokit_success, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_page_secluded.grab_for_iokit_success, 0, "");
2136
2137 extern uint64_t vm_pageout_secluded_burst_count;
2138 SYSCTL_QUAD(_vm, OID_AUTO, pageout_secluded_burst_count, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_pageout_secluded_burst_count, "");
2139
2140 #endif /* CONFIG_SECLUDED_MEMORY */
2141
2142 #include <kern/thread.h>
2143 #include <sys/user.h>
2144
2145 void vm_pageout_io_throttle(void);
2146
2147 void vm_pageout_io_throttle(void) {
2148 struct uthread *uthread = get_bsdthread_info(current_thread());
2149
2150 /*
2151 * thread is marked as a low priority I/O type
2152 * and the I/O we issued while in this cleaning operation
2153 * collided with normal I/O operations... we'll
2154 * delay in order to mitigate the impact of this
2155 * task on the normal operation of the system
2156 */
2157
2158 if (uthread->uu_lowpri_window) {
2159 throttle_lowpri_io(1);
2160 }
2161
2162 }
2163
2164 int
2165 vm_pressure_monitor(
2166 __unused struct proc *p,
2167 struct vm_pressure_monitor_args *uap,
2168 int *retval)
2169 {
2170 kern_return_t kr;
2171 uint32_t pages_reclaimed;
2172 uint32_t pages_wanted;
2173
2174 kr = mach_vm_pressure_monitor(
2175 (boolean_t) uap->wait_for_pressure,
2176 uap->nsecs_monitored,
2177 (uap->pages_reclaimed) ? &pages_reclaimed : NULL,
2178 &pages_wanted);
2179
2180 switch (kr) {
2181 case KERN_SUCCESS:
2182 break;
2183 case KERN_ABORTED:
2184 return EINTR;
2185 default:
2186 return EINVAL;
2187 }
2188
2189 if (uap->pages_reclaimed) {
2190 if (copyout((void *)&pages_reclaimed,
2191 uap->pages_reclaimed,
2192 sizeof (pages_reclaimed)) != 0) {
2193 return EFAULT;
2194 }
2195 }
2196
2197 *retval = (int) pages_wanted;
2198 return 0;
2199 }
2200
2201 int
2202 kas_info(struct proc *p,
2203 struct kas_info_args *uap,
2204 int *retval __unused)
2205 {
2206 #ifdef SECURE_KERNEL
2207 (void)p;
2208 (void)uap;
2209 return ENOTSUP;
2210 #else /* !SECURE_KERNEL */
2211 int selector = uap->selector;
2212 user_addr_t valuep = uap->value;
2213 user_addr_t sizep = uap->size;
2214 user_size_t size;
2215 int error;
2216
2217 if (!kauth_cred_issuser(kauth_cred_get())) {
2218 return EPERM;
2219 }
2220
2221 #if CONFIG_MACF
2222 error = mac_system_check_kas_info(kauth_cred_get(), selector);
2223 if (error) {
2224 return error;
2225 }
2226 #endif
2227
2228 if (IS_64BIT_PROCESS(p)) {
2229 user64_size_t size64;
2230 error = copyin(sizep, &size64, sizeof(size64));
2231 size = (user_size_t)size64;
2232 } else {
2233 user32_size_t size32;
2234 error = copyin(sizep, &size32, sizeof(size32));
2235 size = (user_size_t)size32;
2236 }
2237 if (error) {
2238 return error;
2239 }
2240
2241 switch (selector) {
2242 case KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR:
2243 {
2244 uint64_t slide = vm_kernel_slide;
2245
2246 if (sizeof(slide) != size) {
2247 return EINVAL;
2248 }
2249
2250 if (IS_64BIT_PROCESS(p)) {
2251 user64_size_t size64 = (user64_size_t)size;
2252 error = copyout(&size64, sizep, sizeof(size64));
2253 } else {
2254 user32_size_t size32 = (user32_size_t)size;
2255 error = copyout(&size32, sizep, sizeof(size32));
2256 }
2257 if (error) {
2258 return error;
2259 }
2260
2261 error = copyout(&slide, valuep, sizeof(slide));
2262 if (error) {
2263 return error;
2264 }
2265 }
2266 break;
2267 default:
2268 return EINVAL;
2269 }
2270
2271 return 0;
2272 #endif /* !SECURE_KERNEL */
2273 }
2274
2275
2276 #pragma clang diagnostic push
2277 #pragma clang diagnostic ignored "-Wcast-qual"
2278 #pragma clang diagnostic ignored "-Wunused-function"
2279
2280 static void asserts() {
2281 static_assert(sizeof(vm_min_kernel_address) == sizeof(unsigned long));
2282 static_assert(sizeof(vm_max_kernel_address) == sizeof(unsigned long));
2283 }
2284
2285 SYSCTL_ULONG(_vm, OID_AUTO, vm_min_kernel_address, CTLFLAG_RD, (unsigned long *) &vm_min_kernel_address, "");
2286 SYSCTL_ULONG(_vm, OID_AUTO, vm_max_kernel_address, CTLFLAG_RD, (unsigned long *) &vm_max_kernel_address, "");
2287 #pragma clang diagnostic pop
2288
2289 extern uint32_t vm_page_pages;
2290 SYSCTL_UINT(_vm, OID_AUTO, pages, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_page_pages, 0, "");
2291
2292 #if (__arm__ || __arm64__) && (DEVELOPMENT || DEBUG)
2293 extern int pacified_footprint_suspend;
2294 int footprint_suspend_allowed = 0;
2295 SYSCTL_INT(_vm, OID_AUTO, footprint_suspend_allowed, CTLFLAG_RW | CTLFLAG_LOCKED, &footprint_suspend_allowed, 0, "");
2296
2297 extern void pmap_footprint_suspend(vm_map_t map, boolean_t suspend);
2298 static int
2299 sysctl_vm_footprint_suspend SYSCTL_HANDLER_ARGS
2300 {
2301 #pragma unused(oidp, arg1, arg2)
2302 int error = 0;
2303 int new_value;
2304
2305 if (req->newptr == USER_ADDR_NULL) {
2306 return 0;
2307 }
2308 error = SYSCTL_IN(req, &new_value, sizeof(int));
2309 if (error) {
2310 return error;
2311 }
2312 if (pacified_footprint_suspend &&
2313 !footprint_suspend_allowed) {
2314 if (new_value != 0) {
2315 /* suspends are not allowed... */
2316 return 0;
2317 }
2318 /* ... but let resumes proceed */
2319 }
2320 DTRACE_VM2(footprint_suspend,
2321 vm_map_t, current_map(),
2322 int, new_value);
2323
2324 pmap_footprint_suspend(current_map(), new_value);
2325
2326 return 0;
2327 }
2328 SYSCTL_PROC(_vm, OID_AUTO, footprint_suspend,
2329 CTLTYPE_INT|CTLFLAG_WR|CTLFLAG_ANYBODY|CTLFLAG_LOCKED|CTLFLAG_MASKED,
2330 0, 0, &sysctl_vm_footprint_suspend, "I", "");
2331 #endif /* (__arm__ || __arm64__) && (DEVELOPMENT || DEBUG) */