]> git.saurik.com Git - apple/xnu.git/blob - bsd/kern/kern_sysctl.c
c97123066fabf551657fe924ad95aea21f6708b0
[apple/xnu.git] / bsd / kern / kern_sysctl.c
1 /*
2 * Copyright (c) 2000-2011 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 /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
29 /*-
30 * Copyright (c) 1982, 1986, 1989, 1993
31 * The Regents of the University of California. All rights reserved.
32 *
33 * This code is derived from software contributed to Berkeley by
34 * Mike Karels at Berkeley Software Design, Inc.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution.
44 * 3. All advertising materials mentioning features or use of this software
45 * must display the following acknowledgement:
46 * This product includes software developed by the University of
47 * California, Berkeley and its contributors.
48 * 4. Neither the name of the University nor the names of its contributors
49 * may be used to endorse or promote products derived from this software
50 * without specific prior written permission.
51 *
52 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
53 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
54 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
55 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
56 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
57 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
58 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
59 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
60 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
61 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
62 * SUCH DAMAGE.
63 *
64 * @(#)kern_sysctl.c 8.4 (Berkeley) 4/14/94
65 */
66 /*
67 * NOTICE: This file was modified by SPARTA, Inc. in 2005 to introduce
68 * support for mandatory and extensible security protections. This notice
69 * is included in support of clause 2.2 (b) of the Apple Public License,
70 * Version 2.0.
71 */
72
73 /*
74 * DEPRECATED sysctl system call code
75 *
76 * Everything in this file is deprecated. Sysctls should be handled
77 * by the code in kern_newsysctl.c.
78 * The remaining "case" sections are supposed to be converted into
79 * SYSCTL_*-style definitions, and as soon as all of them are gone,
80 * this source file is supposed to die.
81 *
82 * DO NOT ADD ANY MORE "case" SECTIONS TO THIS FILE, instead define
83 * your sysctl with SYSCTL_INT, SYSCTL_PROC etc. in your source file.
84 */
85
86 #include <sys/param.h>
87 #include <sys/systm.h>
88 #include <sys/kernel.h>
89 #include <sys/malloc.h>
90 #include <sys/proc_internal.h>
91 #include <sys/kauth.h>
92 #include <sys/file_internal.h>
93 #include <sys/vnode_internal.h>
94 #include <sys/unistd.h>
95 #include <sys/buf.h>
96 #include <sys/ioctl.h>
97 #include <sys/namei.h>
98 #include <sys/tty.h>
99 #include <sys/disklabel.h>
100 #include <sys/vm.h>
101 #include <sys/sysctl.h>
102 #include <sys/user.h>
103 #include <sys/aio_kern.h>
104 #include <sys/reboot.h>
105
106 #include <security/audit/audit.h>
107 #include <kern/kalloc.h>
108
109 #include <mach/machine.h>
110 #include <mach/mach_host.h>
111 #include <mach/mach_types.h>
112 #include <mach/vm_param.h>
113 #include <kern/mach_param.h>
114 #include <kern/task.h>
115 #include <kern/thread.h>
116 #include <kern/lock.h>
117 #include <kern/processor.h>
118 #include <kern/debug.h>
119 #include <vm/vm_kern.h>
120 #include <vm/vm_map.h>
121 #include <mach/host_info.h>
122
123 #include <sys/mount_internal.h>
124 #include <sys/kdebug.h>
125 #include <sys/sysproto.h>
126
127 #include <IOKit/IOPlatformExpert.h>
128 #include <pexpert/pexpert.h>
129
130 #include <machine/machine_routines.h>
131 #include <machine/exec.h>
132
133 #include <vm/vm_protos.h>
134 #include <vm/vm_pageout.h>
135 #include <sys/imgsrc.h>
136
137 #if defined(__i386__) || defined(__x86_64__)
138 #include <i386/cpuid.h>
139 #endif
140
141 #if CONFIG_FREEZE
142 #include <sys/kern_memorystatus.h>
143 #endif
144
145 #if KPERF
146 #include <kperf/kperf.h>
147 #endif
148
149 /*
150 * deliberately setting max requests to really high number
151 * so that runaway settings do not cause MALLOC overflows
152 */
153 #define AIO_MAX_REQUESTS (128 * CONFIG_AIO_MAX)
154
155 extern sysctlfn net_sysctl;
156 extern sysctlfn cpu_sysctl;
157 extern int aio_max_requests;
158 extern int aio_max_requests_per_process;
159 extern int aio_worker_threads;
160 extern int lowpri_IO_window_msecs;
161 extern int lowpri_IO_delay_msecs;
162 extern int nx_enabled;
163 extern int speculative_reads_disabled;
164 extern int ignore_is_ssd;
165 extern unsigned int speculative_prefetch_max;
166 extern unsigned int speculative_prefetch_max_iosize;
167 extern unsigned int preheat_pages_max;
168 extern unsigned int preheat_pages_min;
169 extern long numvnodes;
170
171 extern uuid_string_t bootsessionuuid_string;
172
173 extern unsigned int vm_max_delayed_work_limit;
174 extern unsigned int vm_max_batch;
175
176 extern unsigned int vm_page_free_min;
177 extern unsigned int vm_page_free_target;
178 extern unsigned int vm_page_free_reserved;
179 extern unsigned int vm_page_speculative_percentage;
180 extern unsigned int vm_page_speculative_q_age_ms;
181
182 /*
183 * Conditionally allow dtrace to see these functions for debugging purposes.
184 */
185 #ifdef STATIC
186 #undef STATIC
187 #endif
188 #if 0
189 #define STATIC
190 #else
191 #define STATIC static
192 #endif
193
194 extern boolean_t mach_timer_coalescing_enabled;
195
196 extern uint64_t timer_deadline_tracking_bin_1, timer_deadline_tracking_bin_2;
197
198 STATIC void
199 fill_user32_eproc(proc_t, struct user32_eproc *__restrict);
200 STATIC void
201 fill_user32_externproc(proc_t, struct user32_extern_proc *__restrict);
202 STATIC void
203 fill_user64_eproc(proc_t, struct user64_eproc *__restrict);
204 STATIC void
205 fill_user64_proc(proc_t, struct user64_kinfo_proc *__restrict);
206 STATIC void
207 fill_user64_externproc(proc_t, struct user64_extern_proc *__restrict);
208 STATIC void
209 fill_user32_proc(proc_t, struct user32_kinfo_proc *__restrict);
210
211 extern int
212 kdbg_control(int *name, u_int namelen, user_addr_t where, size_t * sizep);
213 #if NFSCLIENT
214 extern int
215 netboot_root(void);
216 #endif
217 int
218 pcsamples_ops(int *name, u_int namelen, user_addr_t where, size_t *sizep,
219 proc_t p);
220 __private_extern__ kern_return_t
221 reset_vmobjectcache(unsigned int val1, unsigned int val2);
222 int
223 sysctl_procargs(int *name, u_int namelen, user_addr_t where,
224 size_t *sizep, proc_t cur_proc);
225 STATIC int
226 sysctl_procargsx(int *name, u_int namelen, user_addr_t where, size_t *sizep,
227 proc_t cur_proc, int argc_yes);
228 int
229 sysctl_struct(user_addr_t oldp, size_t *oldlenp, user_addr_t newp,
230 size_t newlen, void *sp, int len);
231
232 STATIC int sysdoproc_filt_KERN_PROC_PID(proc_t p, void * arg);
233 STATIC int sysdoproc_filt_KERN_PROC_PGRP(proc_t p, void * arg);
234 STATIC int sysdoproc_filt_KERN_PROC_TTY(proc_t p, void * arg);
235 STATIC int sysdoproc_filt_KERN_PROC_UID(proc_t p, void * arg);
236 STATIC int sysdoproc_filt_KERN_PROC_RUID(proc_t p, void * arg);
237 #if CONFIG_LCTX
238 STATIC int sysdoproc_filt_KERN_PROC_LCID(proc_t p, void * arg);
239 #endif
240 int sysdoproc_callback(proc_t p, void *arg);
241
242
243 /* forward declarations for non-static STATIC */
244 STATIC void fill_loadavg64(struct loadavg *la, struct user64_loadavg *la64);
245 STATIC void fill_loadavg32(struct loadavg *la, struct user32_loadavg *la32);
246 STATIC int sysctl_handle_kern_threadname(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
247 STATIC int sysctl_sched_stats(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
248 STATIC int sysctl_sched_stats_enable(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
249 STATIC int sysctl_kdebug_ops SYSCTL_HANDLER_ARGS;
250 STATIC int sysctl_dotranslate SYSCTL_HANDLER_ARGS;
251 STATIC int sysctl_doaffinity SYSCTL_HANDLER_ARGS;
252 #if COUNT_SYSCALLS
253 STATIC int sysctl_docountsyscalls SYSCTL_HANDLER_ARGS;
254 #endif /* COUNT_SYSCALLS */
255 STATIC int sysctl_doprocargs SYSCTL_HANDLER_ARGS;
256 STATIC int sysctl_doprocargs2 SYSCTL_HANDLER_ARGS;
257 STATIC int sysctl_prochandle SYSCTL_HANDLER_ARGS;
258 #if DEBUG
259 STATIC int sysctl_dodebug SYSCTL_HANDLER_ARGS;
260 #endif
261 STATIC int sysctl_aiomax(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
262 STATIC int sysctl_aioprocmax(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
263 STATIC int sysctl_aiothreads(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
264 STATIC int sysctl_maxproc(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
265 STATIC int sysctl_osversion(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
266 STATIC int sysctl_sysctl_bootargs(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
267 STATIC int sysctl_maxvnodes(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
268 STATIC int sysctl_securelvl(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
269 STATIC int sysctl_domainname(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
270 STATIC int sysctl_hostname(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
271 STATIC int sysctl_procname(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
272 STATIC int sysctl_boottime(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
273 STATIC int sysctl_symfile(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
274 #if NFSCLIENT
275 STATIC int sysctl_netboot(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
276 #endif
277 #ifdef CONFIG_IMGSRC_ACCESS
278 STATIC int sysctl_imgsrcdev(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
279 #endif
280 STATIC int sysctl_usrstack(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
281 STATIC int sysctl_usrstack64(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
282 STATIC int sysctl_coredump(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
283 STATIC int sysctl_suid_coredump(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
284 STATIC int sysctl_delayterm(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
285 STATIC int sysctl_rage_vnode(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
286 STATIC int sysctl_kern_check_openevt(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
287 STATIC int sysctl_nx(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
288 STATIC int sysctl_loadavg(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
289 STATIC int sysctl_vm_toggle_address_reuse(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
290 STATIC int sysctl_swapusage(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
291 #if defined(__i386__) || defined(__x86_64__)
292 STATIC int sysctl_sysctl_exec_affinity(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
293 #endif
294 STATIC int fetch_process_cputype( proc_t cur_proc, int *name, u_int namelen, cpu_type_t *cputype);
295 STATIC int sysctl_sysctl_native(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
296 STATIC int sysctl_sysctl_cputype(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
297 STATIC int sysctl_safeboot(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
298 STATIC int sysctl_singleuser(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
299 STATIC int sysctl_slide(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
300
301
302 extern void IORegistrySetOSBuildVersion(char * build_version);
303
304 STATIC void
305 fill_loadavg64(struct loadavg *la, struct user64_loadavg *la64)
306 {
307 la64->ldavg[0] = la->ldavg[0];
308 la64->ldavg[1] = la->ldavg[1];
309 la64->ldavg[2] = la->ldavg[2];
310 la64->fscale = (user64_long_t)la->fscale;
311 }
312
313 STATIC void
314 fill_loadavg32(struct loadavg *la, struct user32_loadavg *la32)
315 {
316 la32->ldavg[0] = la->ldavg[0];
317 la32->ldavg[1] = la->ldavg[1];
318 la32->ldavg[2] = la->ldavg[2];
319 la32->fscale = (user32_long_t)la->fscale;
320 }
321
322 /*
323 * sysctl_mem_hold
324 *
325 * Description: Wire down the callers address map on behalf of sysctl's
326 * that perform their own copy operations while holding
327 * locks e.g. in the paging path, which could lead to a
328 * deadlock, or while holding a spinlock.
329 *
330 * Parameters: addr User buffer address
331 * len User buffer length
332 *
333 * Returns: 0 Success
334 * vslock:ENOMEM Insufficient physical pages to wire
335 * vslock:EACCES Bad protection mode
336 * vslock:EINVAL Invalid parameters
337 *
338 * Notes: This code is invoked for the first OID element where the
339 * CTLFLAG_LOCKED is not specified for a given OID node
340 * element durng OID traversal, and is held for all
341 * subsequent node traversals, and only released after the
342 * leaf node handler invocation is complete.
343 *
344 * Legacy: For legacy scyctl's provided by third party code which
345 * expect funnel protection for calls into their code, this
346 * routine will also take the funnel, which will also only
347 * be released after the leaf node handler is complete.
348 *
349 * This is to support legacy 32 bit BSD KEXTs and legacy 32
350 * bit single threaded filesystem KEXTs and similar code
351 * which relies on funnel protection, e.g. for things like
352 * FSID based sysctl's.
353 *
354 * NEW CODE SHOULD NOT RELY ON THIS BEHAVIOUR! IT WILL BE
355 * REMOVED IN A FUTURE RELASE OF Mac OS X!
356 *
357 * Bugs: This routine does nothing with the new_addr and new_len
358 * at present, but it should, since read from the user space
359 * process adddress space which could potentially trigger
360 * paging may also be occurring deep down. This is due to
361 * a current limitation of the vslock() routine, which will
362 * always request a wired mapping be read/write, due to not
363 * taking an access mode parameter. Note that this could
364 * also cause problems for output on architectures where
365 * write access does not require read acccess if the current
366 * mapping lacks read access.
367 *
368 * XXX: To be moved to kern_newsysctl.c to avoid __private_extern__
369 */
370 int sysctl_mem_lock(user_addr_t old_addr, user_size_t old_len, user_addr_t new_addr, user_size_t new_len);
371 int
372 sysctl_mem_lock(__unused user_addr_t old_addr, __unused user_size_t old_len, __unused user_addr_t new_addr, __unused user_size_t new_len)
373 {
374 return 0;
375 }
376
377 /*
378 * Locking and stats
379 */
380
381 /* sysctl() syscall */
382 int
383 __sysctl(proc_t p, struct __sysctl_args *uap, __unused int32_t *retval)
384 {
385 boolean_t funnel_state = FALSE; /* not held if unknown */
386 int error;
387 size_t savelen = 0, oldlen = 0, newlen;
388 int name[CTL_MAXNAME];
389 int error1;
390 boolean_t vslock_taken = FALSE;
391 boolean_t funnel_taken = FALSE;
392 #if CONFIG_MACF
393 kauth_cred_t my_cred;
394 #endif
395
396 /*
397 * all top-level sysctl names are non-terminal
398 */
399 if (uap->namelen > CTL_MAXNAME || uap->namelen < 2)
400 return (EINVAL);
401 error = copyin(uap->name, &name[0], uap->namelen * sizeof(int));
402 if (error)
403 return (error);
404
405 AUDIT_ARG(ctlname, name, uap->namelen);
406
407 if (proc_is64bit(p)) {
408 /* uap->newlen is a size_t value which grows to 64 bits
409 * when coming from a 64-bit process. since it's doubtful we'll
410 * have a sysctl newp buffer greater than 4GB we shrink it to size_t
411 */
412 newlen = CAST_DOWN(size_t, uap->newlen);
413 }
414 else {
415 newlen = uap->newlen;
416 }
417
418 /*
419 * XXX TODO: push down rights check for CTL_HW OIDs; most duplicate
420 * XXX it anyway, which is a performance sink, and requires use
421 * XXX of SUID root programs (see <rdar://3915692>).
422 *
423 * Note: Opt out of non-leaf node enforcement by removing this
424 * check for the top level OID value, and then adding
425 * CTLFLAG_ANYBODY to the leaf nodes in question. Enforce as
426 * suser for writed in leaf nodes by omitting this flag.
427 * Enforce with a higher granularity by making the leaf node
428 * of type SYSCTL_PROC() in order to provide a procedural
429 * enforcement call site.
430 *
431 * NOTE: This function is called prior to any subfunctions being
432 * called with a fallback to userland_sysctl(); as such, this
433 * permissions check here will veto the fallback operation.
434 */
435 /* CTL_UNSPEC is used to get oid to AUTO_OID */
436 if (uap->new != USER_ADDR_NULL
437 && ((name[0] == CTL_HW)
438 || (name[0] == CTL_VM))
439 && (error = suser(kauth_cred_get(), &p->p_acflag)))
440 return (error);
441
442 // XXX need to relocate into each terminal instead of leaving this here...
443 // XXX macf preemptory check.
444 #if CONFIG_MACF
445 my_cred = kauth_cred_proc_ref(p);
446 error = mac_system_check_sysctl(
447 my_cred,
448 (int *) name,
449 uap->namelen,
450 uap->old,
451 uap->oldlenp,
452 0, /* XXX 1 for CTL_KERN checks */
453 uap->new,
454 newlen
455 );
456 kauth_cred_unref(&my_cred);
457 if (error)
458 return (error);
459 #endif
460
461 if (uap->oldlenp != USER_ADDR_NULL) {
462 uint64_t oldlen64 = fuulong(uap->oldlenp);
463
464 oldlen = CAST_DOWN(size_t, oldlen64);
465 /*
466 * If more than 4G, clamp to 4G - useracc() below will catch
467 * with an EFAULT, if it's actually necessary.
468 */
469 if (oldlen64 > 0x00000000ffffffffULL)
470 oldlen = 0xffffffffUL;
471 }
472
473 if ((name[0] == CTL_VFS || name[0] == CTL_VM)) {
474 /*
475 * Always take the funnel for CTL_VFS and CTL_VM
476 *
477 * XXX We should also take it for any OID without the
478 * XXX CTLFLAG_LOCKED set on it; fix this later!
479 */
480 funnel_state = thread_funnel_set(kernel_flock, TRUE);
481 funnel_taken = TRUE;
482
483 /*
484 * XXX Take the vslock() only when we are copying out; this
485 * XXX erroneously assumes that the copy in will not cause
486 * XXX a fault if caled from the paging path due to the
487 * XXX having been recently touched in order to establish
488 * XXX the input data. This is a bad assumption.
489 *
490 * Note: This is overkill, but third parties might
491 * already call sysctl internally in KEXTs that
492 * implement mass storage drivers. If you are
493 * writing a new KEXT, don't do that.
494 */
495 if(uap->old != USER_ADDR_NULL) {
496 if (!useracc(uap->old, (user_size_t)oldlen, B_WRITE)) {
497 thread_funnel_set(kernel_flock, funnel_state);
498 return (EFAULT);
499 }
500
501 if (oldlen) {
502 if ((error = vslock(uap->old, (user_size_t)oldlen))) {
503 thread_funnel_set(kernel_flock, funnel_state);
504 return(error);
505 }
506 savelen = oldlen;
507 vslock_taken = TRUE;
508 }
509 }
510 }
511
512 /*
513 * XXX convert vfs_sysctl subelements to newsysctl; this is hard
514 * XXX because of VFS_NUMMNTOPS being top level.
515 */
516 error = ENOTSUP;
517 if (name[0] == CTL_VFS) {
518 error = vfs_sysctl(name + 1, uap->namelen - 1, uap->old,
519 &oldlen, uap->new, newlen, p);
520 }
521
522 if (vslock_taken == TRUE) {
523 error1 = vsunlock(uap->old, (user_size_t)savelen, B_WRITE);
524 if (!error)
525 error = error1;
526 }
527
528 if ( (name[0] != CTL_VFS) && (error == ENOTSUP) ) {
529 size_t tmp = oldlen;
530 error = userland_sysctl(p, name, uap->namelen, uap->old, &tmp,
531 uap->new, newlen, &oldlen);
532 }
533
534 /*
535 * If we took the funnel, which we only do for CTL_VFS and CTL_VM on
536 * 32 bit architectures, then drop it.
537 *
538 * XXX the grabbing and dropping need to move into the leaf nodes,
539 * XXX for sysctl's that are not marked CTLFLAG_LOCKED, but this is
540 * XXX true for the vslock, as well. We have a start at a routine
541 * to wrapper this (above), but it's not turned on. The current code
542 * removed the funnel and the vslock() from all but these two top
543 * level OIDs. Note that VFS only needs to take the funnel if the FS
544 * against which it's operating is not thread safe (but since an FS
545 * can be in the paging path, it still needs to take the vslock()).
546 */
547 if (funnel_taken)
548 thread_funnel_set(kernel_flock, funnel_state);
549
550 if ((error) && (error != ENOMEM))
551 return (error);
552
553 if (uap->oldlenp != USER_ADDR_NULL)
554 error = suulong(uap->oldlenp, oldlen);
555
556 return (error);
557 }
558
559 /*
560 * Attributes stored in the kernel.
561 */
562 extern char corefilename[MAXPATHLEN+1];
563 extern int do_coredump;
564 extern int sugid_coredump;
565
566 #if COUNT_SYSCALLS
567 extern int do_count_syscalls;
568 #endif
569
570 #ifdef INSECURE
571 int securelevel = -1;
572 #else
573 int securelevel;
574 #endif
575
576 STATIC int
577 sysctl_doaffinity SYSCTL_HANDLER_ARGS
578 {
579 __unused int cmd = oidp->oid_arg2; /* subcommand*/
580 int *name = arg1; /* oid element argument vector */
581 int namelen = arg2; /* number of oid element arguments */
582 user_addr_t oldp = req->oldptr; /* user buffer copy out address */
583 size_t *oldlenp = &req->oldlen; /* user buffer copy out size */
584 user_addr_t newp = req->newptr; /* user buffer copy in address */
585 // size_t newlen = req->newlen; /* user buffer copy in size */
586
587 int error = ENOTSUP; /* Default to failure */
588
589 proc_t cur_proc = current_proc();
590
591 if (namelen < 1)
592 return (ENOTSUP);
593
594 if (name[0] == 0 && 1 == namelen) {
595 error = sysctl_rdint(oldp, oldlenp, newp,
596 (cur_proc->p_flag & P_AFFINITY) ? 1 : 0);
597 } else if (name[0] == 1 && 2 == namelen) {
598 if (name[1] == 0) {
599 OSBitAndAtomic(~((uint32_t)P_AFFINITY), &cur_proc->p_flag);
600 } else {
601 OSBitOrAtomic(P_AFFINITY, &cur_proc->p_flag);
602 }
603 error = 0;
604 }
605
606 /* adjust index so we return the right required/consumed amount */
607 if (!error)
608 req->oldidx += req->oldlen;
609
610 return (error);
611 }
612 SYSCTL_PROC(_kern, KERN_AFFINITY, affinity, CTLTYPE_NODE|CTLFLAG_RD | CTLFLAG_LOCKED,
613 0, /* Pointer argument (arg1) */
614 0, /* Integer argument (arg2) */
615 sysctl_doaffinity, /* Handler function */
616 NULL, /* Data pointer */
617 "");
618
619 STATIC int
620 sysctl_dotranslate SYSCTL_HANDLER_ARGS
621 {
622 __unused int cmd = oidp->oid_arg2; /* subcommand*/
623 int *name = arg1; /* oid element argument vector */
624 int namelen = arg2; /* number of oid element arguments */
625 user_addr_t oldp = req->oldptr; /* user buffer copy out address */
626 size_t *oldlenp = &req->oldlen; /* user buffer copy out size */
627 user_addr_t newp = req->newptr; /* user buffer copy in address */
628 // size_t newlen = req->newlen; /* user buffer copy in size */
629 int error;
630
631 proc_t cur_proc = current_proc();
632 proc_t p;
633 int istranslated = 0;
634 kauth_cred_t my_cred;
635 uid_t uid;
636
637 if (namelen != 1)
638 return (ENOTSUP);
639
640 p = proc_find(name[0]);
641 if (p == NULL)
642 return (EINVAL);
643
644 my_cred = kauth_cred_proc_ref(p);
645 uid = kauth_cred_getuid(my_cred);
646 kauth_cred_unref(&my_cred);
647 if ((uid != kauth_cred_getuid(kauth_cred_get()))
648 && suser(kauth_cred_get(), &cur_proc->p_acflag)) {
649 proc_rele(p);
650 return (EPERM);
651 }
652
653 istranslated = (p->p_flag & P_TRANSLATED);
654 proc_rele(p);
655 error = sysctl_rdint(oldp, oldlenp, newp,
656 (istranslated != 0) ? 1 : 0);
657
658 /* adjust index so we return the right required/consumed amount */
659 if (!error)
660 req->oldidx += req->oldlen;
661
662 return (error);
663 }
664 /*
665 * XXX make CTLFLAG_RW so sysctl_rdint() will EPERM on attempts to write;
666 * XXX this may not be necessary.
667 */
668 SYSCTL_PROC(_kern, KERN_TRANSLATE, translate, CTLTYPE_NODE|CTLFLAG_RW | CTLFLAG_LOCKED,
669 0, /* Pointer argument (arg1) */
670 0, /* Integer argument (arg2) */
671 sysctl_dotranslate, /* Handler function */
672 NULL, /* Data pointer */
673 "");
674
675 STATIC int
676 sysctl_handle_kern_threadname( __unused struct sysctl_oid *oidp, __unused void *arg1,
677 __unused int arg2, struct sysctl_req *req)
678 {
679 int error;
680 struct uthread *ut = get_bsdthread_info(current_thread());
681 user_addr_t oldp=0, newp=0;
682 size_t *oldlenp=NULL;
683 size_t newlen=0;
684
685 oldp = req->oldptr;
686 oldlenp = &(req->oldlen);
687 newp = req->newptr;
688 newlen = req->newlen;
689
690 /* We want the current length, and maybe the string itself */
691 if(oldlenp) {
692 /* if we have no thread name yet tell'em we want MAXTHREADNAMESIZE - 1 */
693 size_t currlen = MAXTHREADNAMESIZE - 1;
694
695 if(ut->pth_name)
696 /* use length of current thread name */
697 currlen = strlen(ut->pth_name);
698 if(oldp) {
699 if(*oldlenp < currlen)
700 return ENOMEM;
701 /* NOTE - we do not copy the NULL terminator */
702 if(ut->pth_name) {
703 error = copyout(ut->pth_name,oldp,currlen);
704 if(error)
705 return error;
706 }
707 }
708 /* return length of thread name minus NULL terminator (just like strlen) */
709 req->oldidx = currlen;
710 }
711
712 /* We want to set the name to something */
713 if(newp)
714 {
715 if(newlen > (MAXTHREADNAMESIZE - 1))
716 return ENAMETOOLONG;
717 if(!ut->pth_name)
718 {
719 ut->pth_name = (char*)kalloc( MAXTHREADNAMESIZE );
720 if(!ut->pth_name)
721 return ENOMEM;
722 }
723 bzero(ut->pth_name, MAXTHREADNAMESIZE);
724 error = copyin(newp, ut->pth_name, newlen);
725 if(error)
726 return error;
727 }
728
729 return 0;
730 }
731
732 SYSCTL_PROC(_kern, KERN_THREADNAME, threadname, CTLFLAG_ANYBODY | CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_LOCKED, 0, 0, sysctl_handle_kern_threadname,"A","");
733
734 #define BSD_HOST 1
735 STATIC int
736 sysctl_sched_stats(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
737 {
738 host_basic_info_data_t hinfo;
739 kern_return_t kret;
740 uint32_t size;
741 int changed;
742 mach_msg_type_number_t count = HOST_BASIC_INFO_COUNT;
743 struct _processor_statistics_np *buf;
744 int error;
745
746 kret = host_info((host_t)BSD_HOST, HOST_BASIC_INFO, (host_info_t)&hinfo, &count);
747 if (kret != KERN_SUCCESS) {
748 return EINVAL;
749 }
750
751 size = sizeof(struct _processor_statistics_np) * (hinfo.logical_cpu_max + 2); /* One for RT Queue, One for Fair Share Queue */
752
753 if (req->oldlen < size) {
754 return EINVAL;
755 }
756
757 MALLOC(buf, struct _processor_statistics_np*, size, M_TEMP, M_ZERO | M_WAITOK);
758
759 kret = get_sched_statistics(buf, &size);
760 if (kret != KERN_SUCCESS) {
761 error = EINVAL;
762 goto out;
763 }
764
765 error = sysctl_io_opaque(req, buf, size, &changed);
766 if (error) {
767 goto out;
768 }
769
770 if (changed) {
771 panic("Sched info changed?!");
772 }
773 out:
774 FREE(buf, M_TEMP);
775 return error;
776 }
777
778 SYSCTL_PROC(_kern, OID_AUTO, sched_stats, CTLFLAG_LOCKED, 0, 0, sysctl_sched_stats, "-", "");
779
780 STATIC int
781 sysctl_sched_stats_enable(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, __unused struct sysctl_req *req)
782 {
783 boolean_t active;
784 int res;
785
786 if (req->newlen != sizeof(active)) {
787 return EINVAL;
788 }
789
790 res = copyin(req->newptr, &active, sizeof(active));
791 if (res != 0) {
792 return res;
793 }
794
795 return set_sched_stats_active(active);
796 }
797
798 SYSCTL_PROC(_kern, OID_AUTO, sched_stats_enable, CTLFLAG_LOCKED | CTLFLAG_WR, 0, 0, sysctl_sched_stats_enable, "-", "");
799
800 extern int get_kernel_symfile(proc_t, char **);
801
802 #if COUNT_SYSCALLS
803 #define KERN_COUNT_SYSCALLS (KERN_OSTYPE + 1000)
804
805 extern int nsysent;
806 extern int syscalls_log[];
807 extern const char *syscallnames[];
808
809 STATIC int
810 sysctl_docountsyscalls SYSCTL_HANDLER_ARGS
811 {
812 __unused int cmd = oidp->oid_arg2; /* subcommand*/
813 __unused int *name = arg1; /* oid element argument vector */
814 __unused int namelen = arg2; /* number of oid element arguments */
815 user_addr_t oldp = req->oldptr; /* user buffer copy out address */
816 size_t *oldlenp = &req->oldlen; /* user buffer copy out size */
817 user_addr_t newp = req->newptr; /* user buffer copy in address */
818 size_t newlen = req->newlen; /* user buffer copy in size */
819 int error;
820
821 int tmp;
822
823 /* valid values passed in:
824 * = 0 means don't keep called counts for each bsd syscall
825 * > 0 means keep called counts for each bsd syscall
826 * = 2 means dump current counts to the system log
827 * = 3 means reset all counts
828 * for example, to dump current counts:
829 * sysctl -w kern.count_calls=2
830 */
831 error = sysctl_int(oldp, oldlenp, newp, newlen, &tmp);
832 if ( error != 0 ) {
833 return (error);
834 }
835
836 if ( tmp == 1 ) {
837 do_count_syscalls = 1;
838 }
839 else if ( tmp == 0 || tmp == 2 || tmp == 3 ) {
840 int i;
841 for ( i = 0; i < nsysent; i++ ) {
842 if ( syscalls_log[i] != 0 ) {
843 if ( tmp == 2 ) {
844 printf("%d calls - name %s \n", syscalls_log[i], syscallnames[i]);
845 }
846 else {
847 syscalls_log[i] = 0;
848 }
849 }
850 }
851 if ( tmp != 0 ) {
852 do_count_syscalls = 1;
853 }
854 }
855
856 /* adjust index so we return the right required/consumed amount */
857 if (!error)
858 req->oldidx += req->oldlen;
859
860 return (error);
861 }
862 SYSCTL_PROC(_kern, KERN_COUNT_SYSCALLS, count_syscalls, CTLTYPE_NODE|CTLFLAG_RD | CTLFLAG_LOCKED,
863 0, /* Pointer argument (arg1) */
864 0, /* Integer argument (arg2) */
865 sysctl_docountsyscalls, /* Handler function */
866 NULL, /* Data pointer */
867 "");
868 #endif /* COUNT_SYSCALLS */
869
870 #if DEBUG
871 /*
872 * Debugging related system variables.
873 */
874 #if DIAGNOSTIC
875 extern
876 #endif /* DIAGNOSTIC */
877 struct ctldebug debug0, debug1;
878 struct ctldebug debug2, debug3, debug4;
879 struct ctldebug debug5, debug6, debug7, debug8, debug9;
880 struct ctldebug debug10, debug11, debug12, debug13, debug14;
881 struct ctldebug debug15, debug16, debug17, debug18, debug19;
882 STATIC struct ctldebug *debugvars[CTL_DEBUG_MAXID] = {
883 &debug0, &debug1, &debug2, &debug3, &debug4,
884 &debug5, &debug6, &debug7, &debug8, &debug9,
885 &debug10, &debug11, &debug12, &debug13, &debug14,
886 &debug15, &debug16, &debug17, &debug18, &debug19,
887 };
888 STATIC int
889 sysctl_dodebug SYSCTL_HANDLER_ARGS
890 {
891 int cmd = oidp->oid_arg2; /* subcommand*/
892 int *name = arg1; /* oid element argument vector */
893 int namelen = arg2; /* number of oid element arguments */
894 user_addr_t oldp = req->oldptr; /* user buffer copy out address */
895 size_t *oldlenp = &req->oldlen; /* user buffer copy out size */
896 user_addr_t newp = req->newptr; /* user buffer copy in address */
897 size_t newlen = req->newlen; /* user buffer copy in size */
898 int error;
899
900 struct ctldebug *cdp;
901
902 /* all sysctl names at this level are name and field */
903 if (namelen != 1)
904 return (ENOTSUP); /* overloaded */
905 if (cmd < 0 || cmd >= CTL_DEBUG_MAXID)
906 return (ENOTSUP);
907 cdp = debugvars[cmd];
908 if (cdp->debugname == 0)
909 return (ENOTSUP);
910 switch (name[0]) {
911 case CTL_DEBUG_NAME:
912 error = sysctl_rdstring(oldp, oldlenp, newp, cdp->debugname);
913 break;
914 case CTL_DEBUG_VALUE:
915 error = sysctl_int(oldp, oldlenp, newp, newlen, cdp->debugvar);
916 break;
917 default:
918 error = ENOTSUP;
919 break;
920 }
921
922 /* adjust index so we return the right required/consumed amount */
923 if (!error)
924 req->oldidx += req->oldlen;
925
926 return (error);
927 }
928 /*
929 * XXX We mark this RW instead of RD to let sysctl_rdstring() return the
930 * XXX historical error.
931 */
932 SYSCTL_PROC(_debug, CTL_DEBUG_NAME, name, CTLTYPE_NODE|CTLFLAG_RW | CTLFLAG_LOCKED,
933 0, /* Pointer argument (arg1) */
934 CTL_DEBUG_NAME, /* Integer argument (arg2) */
935 sysctl_dodebug, /* Handler function */
936 NULL, /* Data pointer */
937 "Debugging");
938 SYSCTL_PROC(_debug, CTL_DEBUG_VALUE, value, CTLTYPE_NODE|CTLFLAG_RW | CTLFLAG_LOCKED,
939 0, /* Pointer argument (arg1) */
940 CTL_DEBUG_VALUE, /* Integer argument (arg2) */
941 sysctl_dodebug, /* Handler function */
942 NULL, /* Data pointer */
943 "Debugging");
944 #endif /* DEBUG */
945
946 /*
947 * The following sysctl_* functions should not be used
948 * any more, as they can only cope with callers in
949 * user mode: Use new-style
950 * sysctl_io_number()
951 * sysctl_io_string()
952 * sysctl_io_opaque()
953 * instead.
954 */
955
956 /*
957 * Validate parameters and get old / set new parameters
958 * for an integer-valued sysctl function.
959 */
960 int
961 sysctl_int(user_addr_t oldp, size_t *oldlenp,
962 user_addr_t newp, size_t newlen, int *valp)
963 {
964 int error = 0;
965
966 if (oldp != USER_ADDR_NULL && oldlenp == NULL)
967 return (EFAULT);
968 if (oldp && *oldlenp < sizeof(int))
969 return (ENOMEM);
970 if (newp && newlen != sizeof(int))
971 return (EINVAL);
972 *oldlenp = sizeof(int);
973 if (oldp)
974 error = copyout(valp, oldp, sizeof(int));
975 if (error == 0 && newp) {
976 error = copyin(newp, valp, sizeof(int));
977 AUDIT_ARG(value32, *valp);
978 }
979 return (error);
980 }
981
982 /*
983 * As above, but read-only.
984 */
985 int
986 sysctl_rdint(user_addr_t oldp, size_t *oldlenp, user_addr_t newp, int val)
987 {
988 int error = 0;
989
990 if (oldp != USER_ADDR_NULL && oldlenp == NULL)
991 return (EFAULT);
992 if (oldp && *oldlenp < sizeof(int))
993 return (ENOMEM);
994 if (newp)
995 return (EPERM);
996 *oldlenp = sizeof(int);
997 if (oldp)
998 error = copyout((caddr_t)&val, oldp, sizeof(int));
999 return (error);
1000 }
1001
1002 /*
1003 * Validate parameters and get old / set new parameters
1004 * for an quad(64bit)-valued sysctl function.
1005 */
1006 int
1007 sysctl_quad(user_addr_t oldp, size_t *oldlenp,
1008 user_addr_t newp, size_t newlen, quad_t *valp)
1009 {
1010 int error = 0;
1011
1012 if (oldp != USER_ADDR_NULL && oldlenp == NULL)
1013 return (EFAULT);
1014 if (oldp && *oldlenp < sizeof(quad_t))
1015 return (ENOMEM);
1016 if (newp && newlen != sizeof(quad_t))
1017 return (EINVAL);
1018 *oldlenp = sizeof(quad_t);
1019 if (oldp)
1020 error = copyout(valp, oldp, sizeof(quad_t));
1021 if (error == 0 && newp)
1022 error = copyin(newp, valp, sizeof(quad_t));
1023 return (error);
1024 }
1025
1026 /*
1027 * As above, but read-only.
1028 */
1029 int
1030 sysctl_rdquad(user_addr_t oldp, size_t *oldlenp, user_addr_t newp, quad_t val)
1031 {
1032 int error = 0;
1033
1034 if (oldp != USER_ADDR_NULL && oldlenp == NULL)
1035 return (EFAULT);
1036 if (oldp && *oldlenp < sizeof(quad_t))
1037 return (ENOMEM);
1038 if (newp)
1039 return (EPERM);
1040 *oldlenp = sizeof(quad_t);
1041 if (oldp)
1042 error = copyout((caddr_t)&val, oldp, sizeof(quad_t));
1043 return (error);
1044 }
1045
1046 /*
1047 * Validate parameters and get old / set new parameters
1048 * for a string-valued sysctl function. Unlike sysctl_string, if you
1049 * give it a too small (but larger than 0 bytes) buffer, instead of
1050 * returning ENOMEM, it truncates the returned string to the buffer
1051 * size. This preserves the semantics of some library routines
1052 * implemented via sysctl, which truncate their returned data, rather
1053 * than simply returning an error. The returned string is always NUL
1054 * terminated.
1055 */
1056 int
1057 sysctl_trstring(user_addr_t oldp, size_t *oldlenp,
1058 user_addr_t newp, size_t newlen, char *str, int maxlen)
1059 {
1060 int len, copylen, error = 0;
1061
1062 if (oldp != USER_ADDR_NULL && oldlenp == NULL)
1063 return (EFAULT);
1064 copylen = len = strlen(str) + 1;
1065 if (oldp && (len < 0 || *oldlenp < 1))
1066 return (ENOMEM);
1067 if (oldp && (*oldlenp < (size_t)len))
1068 copylen = *oldlenp + 1;
1069 if (newp && (maxlen < 0 || newlen >= (size_t)maxlen))
1070 return (EINVAL);
1071 *oldlenp = copylen - 1; /* deal with NULL strings correctly */
1072 if (oldp) {
1073 error = copyout(str, oldp, copylen);
1074 if (!error) {
1075 unsigned char c = 0;
1076 /* NUL terminate */
1077 oldp += *oldlenp;
1078 error = copyout((void *)&c, oldp, sizeof(char));
1079 }
1080 }
1081 if (error == 0 && newp) {
1082 error = copyin(newp, str, newlen);
1083 str[newlen] = 0;
1084 AUDIT_ARG(text, (char *)str);
1085 }
1086 return (error);
1087 }
1088
1089 /*
1090 * Validate parameters and get old / set new parameters
1091 * for a string-valued sysctl function.
1092 */
1093 int
1094 sysctl_string(user_addr_t oldp, size_t *oldlenp,
1095 user_addr_t newp, size_t newlen, char *str, int maxlen)
1096 {
1097 int len, error = 0;
1098
1099 if (oldp != USER_ADDR_NULL && oldlenp == NULL)
1100 return (EFAULT);
1101 len = strlen(str) + 1;
1102 if (oldp && (len < 0 || *oldlenp < (size_t)len))
1103 return (ENOMEM);
1104 if (newp && (maxlen < 0 || newlen >= (size_t)maxlen))
1105 return (EINVAL);
1106 *oldlenp = len -1; /* deal with NULL strings correctly */
1107 if (oldp) {
1108 error = copyout(str, oldp, len);
1109 }
1110 if (error == 0 && newp) {
1111 error = copyin(newp, str, newlen);
1112 str[newlen] = 0;
1113 AUDIT_ARG(text, (char *)str);
1114 }
1115 return (error);
1116 }
1117
1118 /*
1119 * As above, but read-only.
1120 */
1121 int
1122 sysctl_rdstring(user_addr_t oldp, size_t *oldlenp,
1123 user_addr_t newp, char *str)
1124 {
1125 int len, error = 0;
1126
1127 if (oldp != USER_ADDR_NULL && oldlenp == NULL)
1128 return (EFAULT);
1129 len = strlen(str) + 1;
1130 if (oldp && *oldlenp < (size_t)len)
1131 return (ENOMEM);
1132 if (newp)
1133 return (EPERM);
1134 *oldlenp = len;
1135 if (oldp)
1136 error = copyout(str, oldp, len);
1137 return (error);
1138 }
1139
1140 /*
1141 * Validate parameters and get old / set new parameters
1142 * for a structure oriented sysctl function.
1143 */
1144 int
1145 sysctl_struct(user_addr_t oldp, size_t *oldlenp,
1146 user_addr_t newp, size_t newlen, void *sp, int len)
1147 {
1148 int error = 0;
1149
1150 if (oldp != USER_ADDR_NULL && oldlenp == NULL)
1151 return (EFAULT);
1152 if (oldp && (len < 0 || *oldlenp < (size_t)len))
1153 return (ENOMEM);
1154 if (newp && (len < 0 || newlen > (size_t)len))
1155 return (EINVAL);
1156 if (oldp) {
1157 *oldlenp = len;
1158 error = copyout(sp, oldp, len);
1159 }
1160 if (error == 0 && newp)
1161 error = copyin(newp, sp, len);
1162 return (error);
1163 }
1164
1165 /*
1166 * Validate parameters and get old parameters
1167 * for a structure oriented sysctl function.
1168 */
1169 int
1170 sysctl_rdstruct(user_addr_t oldp, size_t *oldlenp,
1171 user_addr_t newp, void *sp, int len)
1172 {
1173 int error = 0;
1174
1175 if (oldp != USER_ADDR_NULL && oldlenp == NULL)
1176 return (EFAULT);
1177 if (oldp && (len < 0 || *oldlenp < (size_t)len))
1178 return (ENOMEM);
1179 if (newp)
1180 return (EPERM);
1181 *oldlenp = len;
1182 if (oldp)
1183 error = copyout(sp, oldp, len);
1184 return (error);
1185 }
1186
1187 STATIC int
1188 sysdoproc_filt_KERN_PROC_PID(proc_t p, void * arg)
1189 {
1190 if (p->p_pid != (pid_t)*(int*)arg)
1191 return(0);
1192 else
1193 return(1);
1194 }
1195
1196 STATIC int
1197 sysdoproc_filt_KERN_PROC_PGRP(proc_t p, void * arg)
1198 {
1199 if (p->p_pgrpid != (pid_t)*(int*)arg)
1200 return(0);
1201 else
1202 return(1);
1203 }
1204
1205 STATIC int
1206 sysdoproc_filt_KERN_PROC_TTY(proc_t p, void * arg)
1207 {
1208 boolean_t funnel_state;
1209 int retval;
1210 struct tty *tp;
1211
1212
1213 funnel_state = thread_funnel_set(kernel_flock, TRUE);
1214 /* This is very racy but list lock is held.. Hmmm. */
1215 if ((p->p_flag & P_CONTROLT) == 0 ||
1216 (p->p_pgrp == NULL) || (p->p_pgrp->pg_session == NULL) ||
1217 (tp = SESSION_TP(p->p_pgrp->pg_session)) == TTY_NULL ||
1218 tp->t_dev != (dev_t)*(int*)arg)
1219 retval = 0;
1220 else
1221 retval = 1;
1222
1223 thread_funnel_set(kernel_flock, funnel_state);
1224
1225 return(retval);
1226 }
1227
1228 STATIC int
1229 sysdoproc_filt_KERN_PROC_UID(proc_t p, void * arg)
1230 {
1231 kauth_cred_t my_cred;
1232 uid_t uid;
1233
1234 if (p->p_ucred == NULL)
1235 return(0);
1236 my_cred = kauth_cred_proc_ref(p);
1237 uid = kauth_cred_getuid(my_cred);
1238 kauth_cred_unref(&my_cred);
1239
1240 if (uid != (uid_t)*(int*)arg)
1241 return(0);
1242 else
1243 return(1);
1244 }
1245
1246
1247 STATIC int
1248 sysdoproc_filt_KERN_PROC_RUID(proc_t p, void * arg)
1249 {
1250 kauth_cred_t my_cred;
1251 uid_t ruid;
1252
1253 if (p->p_ucred == NULL)
1254 return(0);
1255 my_cred = kauth_cred_proc_ref(p);
1256 ruid = kauth_cred_getruid(my_cred);
1257 kauth_cred_unref(&my_cred);
1258
1259 if (ruid != (uid_t)*(int*)arg)
1260 return(0);
1261 else
1262 return(1);
1263 }
1264
1265 #if CONFIG_LCTX
1266 STATIC int
1267 sysdoproc_filt_KERN_PROC_LCID(proc_t p, void * arg)
1268 {
1269 if ((p->p_lctx == NULL) ||
1270 (p->p_lctx->lc_id != (pid_t)*(int*)arg))
1271 return(0);
1272 else
1273 return(1);
1274 }
1275 #endif
1276
1277 /*
1278 * try over estimating by 5 procs
1279 */
1280 #define KERN_PROCSLOP (5 * sizeof (struct kinfo_proc))
1281 struct sysdoproc_args {
1282 int buflen;
1283 void *kprocp;
1284 boolean_t is_64_bit;
1285 user_addr_t dp;
1286 size_t needed;
1287 int sizeof_kproc;
1288 int *errorp;
1289 int uidcheck;
1290 int ruidcheck;
1291 int ttycheck;
1292 int uidval;
1293 };
1294
1295 int
1296 sysdoproc_callback(proc_t p, void *arg)
1297 {
1298 struct sysdoproc_args *args = arg;
1299
1300 if (args->buflen >= args->sizeof_kproc) {
1301 if ((args->ruidcheck != 0) && (sysdoproc_filt_KERN_PROC_RUID(p, &args->uidval) == 0))
1302 return (PROC_RETURNED);
1303 if ((args->uidcheck != 0) && (sysdoproc_filt_KERN_PROC_UID(p, &args->uidval) == 0))
1304 return (PROC_RETURNED);
1305 if ((args->ttycheck != 0) && (sysdoproc_filt_KERN_PROC_TTY(p, &args->uidval) == 0))
1306 return (PROC_RETURNED);
1307
1308 bzero(args->kprocp, args->sizeof_kproc);
1309 if (args->is_64_bit)
1310 fill_user64_proc(p, args->kprocp);
1311 else
1312 fill_user32_proc(p, args->kprocp);
1313 int error = copyout(args->kprocp, args->dp, args->sizeof_kproc);
1314 if (error) {
1315 *args->errorp = error;
1316 return (PROC_RETURNED_DONE);
1317 }
1318 args->dp += args->sizeof_kproc;
1319 args->buflen -= args->sizeof_kproc;
1320 }
1321 args->needed += args->sizeof_kproc;
1322 return (PROC_RETURNED);
1323 }
1324
1325 SYSCTL_NODE(_kern, KERN_PROC, proc, CTLFLAG_RD | CTLFLAG_LOCKED, 0, "");
1326 STATIC int
1327 sysctl_prochandle SYSCTL_HANDLER_ARGS
1328 {
1329 int cmd = oidp->oid_arg2; /* subcommand for multiple nodes */
1330 int *name = arg1; /* oid element argument vector */
1331 int namelen = arg2; /* number of oid element arguments */
1332 user_addr_t where = req->oldptr;/* user buffer copy out address */
1333
1334 user_addr_t dp = where;
1335 size_t needed = 0;
1336 int buflen = where != USER_ADDR_NULL ? req->oldlen : 0;
1337 int error = 0;
1338 boolean_t is_64_bit = proc_is64bit(current_proc());
1339 struct user32_kinfo_proc user32_kproc;
1340 struct user64_kinfo_proc user_kproc;
1341 int sizeof_kproc;
1342 void *kprocp;
1343 int (*filterfn)(proc_t, void *) = 0;
1344 struct sysdoproc_args args;
1345 int uidcheck = 0;
1346 int ruidcheck = 0;
1347 int ttycheck = 0;
1348
1349 if (namelen != 1 && !(namelen == 0 && cmd == KERN_PROC_ALL))
1350 return (EINVAL);
1351
1352 if (is_64_bit) {
1353 sizeof_kproc = sizeof(user_kproc);
1354 kprocp = &user_kproc;
1355 } else {
1356 sizeof_kproc = sizeof(user32_kproc);
1357 kprocp = &user32_kproc;
1358 }
1359
1360 switch (cmd) {
1361
1362 case KERN_PROC_PID:
1363 filterfn = sysdoproc_filt_KERN_PROC_PID;
1364 break;
1365
1366 case KERN_PROC_PGRP:
1367 filterfn = sysdoproc_filt_KERN_PROC_PGRP;
1368 break;
1369
1370 case KERN_PROC_TTY:
1371 ttycheck = 1;
1372 break;
1373
1374 case KERN_PROC_UID:
1375 uidcheck = 1;
1376 break;
1377
1378 case KERN_PROC_RUID:
1379 ruidcheck = 1;
1380 break;
1381
1382 #if CONFIG_LCTX
1383 case KERN_PROC_LCID:
1384 filterfn = sysdoproc_filt_KERN_PROC_LCID;
1385 break;
1386 #endif
1387 case KERN_PROC_ALL:
1388 break;
1389
1390 default:
1391 /* must be kern.proc.<unknown> */
1392 return (ENOTSUP);
1393 }
1394
1395 error = 0;
1396 args.buflen = buflen;
1397 args.kprocp = kprocp;
1398 args.is_64_bit = is_64_bit;
1399 args.dp = dp;
1400 args.needed = needed;
1401 args.errorp = &error;
1402 args.uidcheck = uidcheck;
1403 args.ruidcheck = ruidcheck;
1404 args.ttycheck = ttycheck;
1405 args.sizeof_kproc = sizeof_kproc;
1406 if (namelen)
1407 args.uidval = name[0];
1408
1409 proc_iterate((PROC_ALLPROCLIST | PROC_ZOMBPROCLIST),
1410 sysdoproc_callback, &args, filterfn, name);
1411
1412 if (error)
1413 return (error);
1414
1415 dp = args.dp;
1416 needed = args.needed;
1417
1418 if (where != USER_ADDR_NULL) {
1419 req->oldlen = dp - where;
1420 if (needed > req->oldlen)
1421 return (ENOMEM);
1422 } else {
1423 needed += KERN_PROCSLOP;
1424 req->oldlen = needed;
1425 }
1426 /* adjust index so we return the right required/consumed amount */
1427 req->oldidx += req->oldlen;
1428 return (0);
1429 }
1430
1431 /*
1432 * We specify the subcommand code for multiple nodes as the 'req->arg2' value
1433 * in the sysctl declaration itself, which comes into the handler function
1434 * as 'oidp->oid_arg2'.
1435 *
1436 * For these particular sysctls, since they have well known OIDs, we could
1437 * have just obtained it from the '((int *)arg1)[0]' parameter, but that would
1438 * not demonstrate how to handle multiple sysctls that used OID_AUTO instead
1439 * of a well known value with a common handler function. This is desirable,
1440 * because we want well known values to "go away" at some future date.
1441 *
1442 * It should be noted that the value of '((int *)arg1)[1]' is used for many
1443 * an integer parameter to the subcommand for many of these sysctls; we'd
1444 * rather have used '((int *)arg1)[0]' for that, or even better, an element
1445 * in a structure passed in as the the 'newp' argument to sysctlbyname(3),
1446 * and then use leaf-node permissions enforcement, but that would have
1447 * necessitated modifying user space code to correspond to the interface
1448 * change, and we are striving for binary backward compatibility here; even
1449 * though these are SPI, and not intended for use by user space applications
1450 * which are not themselves system tools or libraries, some applications
1451 * have erroneously used them.
1452 */
1453 SYSCTL_PROC(_kern_proc, KERN_PROC_ALL, all, CTLTYPE_NODE|CTLFLAG_RD | CTLFLAG_LOCKED,
1454 0, /* Pointer argument (arg1) */
1455 KERN_PROC_ALL, /* Integer argument (arg2) */
1456 sysctl_prochandle, /* Handler function */
1457 NULL, /* Data is size variant on ILP32/LP64 */
1458 "");
1459 SYSCTL_PROC(_kern_proc, KERN_PROC_PID, pid, CTLTYPE_NODE|CTLFLAG_RD | CTLFLAG_LOCKED,
1460 0, /* Pointer argument (arg1) */
1461 KERN_PROC_PID, /* Integer argument (arg2) */
1462 sysctl_prochandle, /* Handler function */
1463 NULL, /* Data is size variant on ILP32/LP64 */
1464 "");
1465 SYSCTL_PROC(_kern_proc, KERN_PROC_TTY, tty, CTLTYPE_NODE|CTLFLAG_RD | CTLFLAG_LOCKED,
1466 0, /* Pointer argument (arg1) */
1467 KERN_PROC_TTY, /* Integer argument (arg2) */
1468 sysctl_prochandle, /* Handler function */
1469 NULL, /* Data is size variant on ILP32/LP64 */
1470 "");
1471 SYSCTL_PROC(_kern_proc, KERN_PROC_PGRP, pgrp, CTLTYPE_NODE|CTLFLAG_RD | CTLFLAG_LOCKED,
1472 0, /* Pointer argument (arg1) */
1473 KERN_PROC_PGRP, /* Integer argument (arg2) */
1474 sysctl_prochandle, /* Handler function */
1475 NULL, /* Data is size variant on ILP32/LP64 */
1476 "");
1477 SYSCTL_PROC(_kern_proc, KERN_PROC_UID, uid, CTLTYPE_NODE|CTLFLAG_RD | CTLFLAG_LOCKED,
1478 0, /* Pointer argument (arg1) */
1479 KERN_PROC_UID, /* Integer argument (arg2) */
1480 sysctl_prochandle, /* Handler function */
1481 NULL, /* Data is size variant on ILP32/LP64 */
1482 "");
1483 SYSCTL_PROC(_kern_proc, KERN_PROC_RUID, ruid, CTLTYPE_NODE|CTLFLAG_RD | CTLFLAG_LOCKED,
1484 0, /* Pointer argument (arg1) */
1485 KERN_PROC_RUID, /* Integer argument (arg2) */
1486 sysctl_prochandle, /* Handler function */
1487 NULL, /* Data is size variant on ILP32/LP64 */
1488 "");
1489 SYSCTL_PROC(_kern_proc, KERN_PROC_LCID, lcid, CTLTYPE_NODE|CTLFLAG_RD | CTLFLAG_LOCKED,
1490 0, /* Pointer argument (arg1) */
1491 KERN_PROC_LCID, /* Integer argument (arg2) */
1492 sysctl_prochandle, /* Handler function */
1493 NULL, /* Data is size variant on ILP32/LP64 */
1494 "");
1495
1496
1497 /*
1498 * Fill in non-zero fields of an eproc structure for the specified process.
1499 */
1500 STATIC void
1501 fill_user32_eproc(proc_t p, struct user32_eproc *__restrict ep)
1502 {
1503 struct tty *tp;
1504 struct pgrp *pg;
1505 struct session *sessp;
1506 kauth_cred_t my_cred;
1507
1508 pg = proc_pgrp(p);
1509 sessp = proc_session(p);
1510
1511 if (pg != PGRP_NULL) {
1512 ep->e_pgid = p->p_pgrpid;
1513 ep->e_jobc = pg->pg_jobc;
1514 if (sessp != SESSION_NULL && sessp->s_ttyvp)
1515 ep->e_flag = EPROC_CTTY;
1516 }
1517 #if CONFIG_LCTX
1518 if (p->p_lctx)
1519 ep->e_lcid = p->p_lctx->lc_id;
1520 #endif
1521 ep->e_ppid = p->p_ppid;
1522 if (p->p_ucred) {
1523 my_cred = kauth_cred_proc_ref(p);
1524
1525 /* A fake historical pcred */
1526 ep->e_pcred.p_ruid = kauth_cred_getruid(my_cred);
1527 ep->e_pcred.p_svuid = kauth_cred_getsvuid(my_cred);
1528 ep->e_pcred.p_rgid = kauth_cred_getrgid(my_cred);
1529 ep->e_pcred.p_svgid = kauth_cred_getsvgid(my_cred);
1530
1531 /* A fake historical *kauth_cred_t */
1532 ep->e_ucred.cr_ref = my_cred->cr_ref;
1533 ep->e_ucred.cr_uid = kauth_cred_getuid(my_cred);
1534 ep->e_ucred.cr_ngroups = posix_cred_get(my_cred)->cr_ngroups;
1535 bcopy(posix_cred_get(my_cred)->cr_groups,
1536 ep->e_ucred.cr_groups, NGROUPS * sizeof (gid_t));
1537
1538 kauth_cred_unref(&my_cred);
1539 }
1540
1541 if ((p->p_flag & P_CONTROLT) && (sessp != SESSION_NULL) &&
1542 (tp = SESSION_TP(sessp))) {
1543 ep->e_tdev = tp->t_dev;
1544 ep->e_tpgid = sessp->s_ttypgrpid;
1545 } else
1546 ep->e_tdev = NODEV;
1547
1548 if (sessp != SESSION_NULL) {
1549 if (SESS_LEADER(p, sessp))
1550 ep->e_flag |= EPROC_SLEADER;
1551 session_rele(sessp);
1552 }
1553 if (pg != PGRP_NULL)
1554 pg_rele(pg);
1555 }
1556
1557 /*
1558 * Fill in non-zero fields of an LP64 eproc structure for the specified process.
1559 */
1560 STATIC void
1561 fill_user64_eproc(proc_t p, struct user64_eproc *__restrict ep)
1562 {
1563 struct tty *tp;
1564 struct pgrp *pg;
1565 struct session *sessp;
1566 kauth_cred_t my_cred;
1567
1568 pg = proc_pgrp(p);
1569 sessp = proc_session(p);
1570
1571 if (pg != PGRP_NULL) {
1572 ep->e_pgid = p->p_pgrpid;
1573 ep->e_jobc = pg->pg_jobc;
1574 if (sessp != SESSION_NULL && sessp->s_ttyvp)
1575 ep->e_flag = EPROC_CTTY;
1576 }
1577 #if CONFIG_LCTX
1578 if (p->p_lctx)
1579 ep->e_lcid = p->p_lctx->lc_id;
1580 #endif
1581 ep->e_ppid = p->p_ppid;
1582 if (p->p_ucred) {
1583 my_cred = kauth_cred_proc_ref(p);
1584
1585 /* A fake historical pcred */
1586 ep->e_pcred.p_ruid = kauth_cred_getruid(my_cred);
1587 ep->e_pcred.p_svuid = kauth_cred_getsvuid(my_cred);
1588 ep->e_pcred.p_rgid = kauth_cred_getrgid(my_cred);
1589 ep->e_pcred.p_svgid = kauth_cred_getsvgid(my_cred);
1590
1591 /* A fake historical *kauth_cred_t */
1592 ep->e_ucred.cr_ref = my_cred->cr_ref;
1593 ep->e_ucred.cr_uid = kauth_cred_getuid(my_cred);
1594 ep->e_ucred.cr_ngroups = posix_cred_get(my_cred)->cr_ngroups;
1595 bcopy(posix_cred_get(my_cred)->cr_groups,
1596 ep->e_ucred.cr_groups, NGROUPS * sizeof (gid_t));
1597
1598 kauth_cred_unref(&my_cred);
1599 }
1600
1601 if ((p->p_flag & P_CONTROLT) && (sessp != SESSION_NULL) &&
1602 (tp = SESSION_TP(sessp))) {
1603 ep->e_tdev = tp->t_dev;
1604 ep->e_tpgid = sessp->s_ttypgrpid;
1605 } else
1606 ep->e_tdev = NODEV;
1607
1608 if (sessp != SESSION_NULL) {
1609 if (SESS_LEADER(p, sessp))
1610 ep->e_flag |= EPROC_SLEADER;
1611 session_rele(sessp);
1612 }
1613 if (pg != PGRP_NULL)
1614 pg_rele(pg);
1615 }
1616
1617 /*
1618 * Fill in an eproc structure for the specified process.
1619 * bzeroed by our caller, so only set non-zero fields.
1620 */
1621 STATIC void
1622 fill_user32_externproc(proc_t p, struct user32_extern_proc *__restrict exp)
1623 {
1624 exp->p_starttime.tv_sec = p->p_start.tv_sec;
1625 exp->p_starttime.tv_usec = p->p_start.tv_usec;
1626 exp->p_flag = p->p_flag;
1627 if (p->p_lflag & P_LTRACED)
1628 exp->p_flag |= P_TRACED;
1629 if (p->p_lflag & P_LPPWAIT)
1630 exp->p_flag |= P_PPWAIT;
1631 if (p->p_lflag & P_LEXIT)
1632 exp->p_flag |= P_WEXIT;
1633 exp->p_stat = p->p_stat;
1634 exp->p_pid = p->p_pid;
1635 exp->p_oppid = p->p_oppid;
1636 /* Mach related */
1637 exp->user_stack = p->user_stack;
1638 exp->p_debugger = p->p_debugger;
1639 exp->sigwait = p->sigwait;
1640 /* scheduling */
1641 #ifdef _PROC_HAS_SCHEDINFO_
1642 exp->p_estcpu = p->p_estcpu;
1643 exp->p_pctcpu = p->p_pctcpu;
1644 exp->p_slptime = p->p_slptime;
1645 #endif
1646 exp->p_realtimer.it_interval.tv_sec =
1647 (user32_time_t)p->p_realtimer.it_interval.tv_sec;
1648 exp->p_realtimer.it_interval.tv_usec =
1649 (__int32_t)p->p_realtimer.it_interval.tv_usec;
1650
1651 exp->p_realtimer.it_value.tv_sec =
1652 (user32_time_t)p->p_realtimer.it_value.tv_sec;
1653 exp->p_realtimer.it_value.tv_usec =
1654 (__int32_t)p->p_realtimer.it_value.tv_usec;
1655
1656 exp->p_rtime.tv_sec = (user32_time_t)p->p_rtime.tv_sec;
1657 exp->p_rtime.tv_usec = (__int32_t)p->p_rtime.tv_usec;
1658
1659 exp->p_sigignore = p->p_sigignore;
1660 exp->p_sigcatch = p->p_sigcatch;
1661 exp->p_priority = p->p_priority;
1662 exp->p_nice = p->p_nice;
1663 bcopy(&p->p_comm, &exp->p_comm, MAXCOMLEN);
1664 exp->p_xstat = p->p_xstat;
1665 exp->p_acflag = p->p_acflag;
1666 }
1667
1668 /*
1669 * Fill in an LP64 version of extern_proc structure for the specified process.
1670 */
1671 STATIC void
1672 fill_user64_externproc(proc_t p, struct user64_extern_proc *__restrict exp)
1673 {
1674 exp->p_starttime.tv_sec = p->p_start.tv_sec;
1675 exp->p_starttime.tv_usec = p->p_start.tv_usec;
1676 exp->p_flag = p->p_flag;
1677 if (p->p_lflag & P_LTRACED)
1678 exp->p_flag |= P_TRACED;
1679 if (p->p_lflag & P_LPPWAIT)
1680 exp->p_flag |= P_PPWAIT;
1681 if (p->p_lflag & P_LEXIT)
1682 exp->p_flag |= P_WEXIT;
1683 exp->p_stat = p->p_stat;
1684 exp->p_pid = p->p_pid;
1685 exp->p_oppid = p->p_oppid;
1686 /* Mach related */
1687 exp->user_stack = p->user_stack;
1688 exp->p_debugger = p->p_debugger;
1689 exp->sigwait = p->sigwait;
1690 /* scheduling */
1691 #ifdef _PROC_HAS_SCHEDINFO_
1692 exp->p_estcpu = p->p_estcpu;
1693 exp->p_pctcpu = p->p_pctcpu;
1694 exp->p_slptime = p->p_slptime;
1695 #endif
1696 exp->p_realtimer.it_interval.tv_sec = p->p_realtimer.it_interval.tv_sec;
1697 exp->p_realtimer.it_interval.tv_usec = p->p_realtimer.it_interval.tv_usec;
1698
1699 exp->p_realtimer.it_value.tv_sec = p->p_realtimer.it_value.tv_sec;
1700 exp->p_realtimer.it_value.tv_usec = p->p_realtimer.it_value.tv_usec;
1701
1702 exp->p_rtime.tv_sec = p->p_rtime.tv_sec;
1703 exp->p_rtime.tv_usec = p->p_rtime.tv_usec;
1704
1705 exp->p_sigignore = p->p_sigignore;
1706 exp->p_sigcatch = p->p_sigcatch;
1707 exp->p_priority = p->p_priority;
1708 exp->p_nice = p->p_nice;
1709 bcopy(&p->p_comm, &exp->p_comm, MAXCOMLEN);
1710 exp->p_xstat = p->p_xstat;
1711 exp->p_acflag = p->p_acflag;
1712 }
1713
1714 STATIC void
1715 fill_user32_proc(proc_t p, struct user32_kinfo_proc *__restrict kp)
1716 {
1717 /* on a 64 bit kernel, 32 bit users get some truncated information */
1718 fill_user32_externproc(p, &kp->kp_proc);
1719 fill_user32_eproc(p, &kp->kp_eproc);
1720 }
1721
1722 STATIC void
1723 fill_user64_proc(proc_t p, struct user64_kinfo_proc *__restrict kp)
1724 {
1725 fill_user64_externproc(p, &kp->kp_proc);
1726 fill_user64_eproc(p, &kp->kp_eproc);
1727 }
1728
1729 STATIC int
1730 sysctl_kdebug_ops SYSCTL_HANDLER_ARGS
1731 {
1732 __unused int cmd = oidp->oid_arg2; /* subcommand*/
1733 int *name = arg1; /* oid element argument vector */
1734 int namelen = arg2; /* number of oid element arguments */
1735 user_addr_t oldp = req->oldptr; /* user buffer copy out address */
1736 size_t *oldlenp = &req->oldlen; /* user buffer copy out size */
1737 // user_addr_t newp = req->newptr; /* user buffer copy in address */
1738 // size_t newlen = req->newlen; /* user buffer copy in size */
1739
1740 proc_t p = current_proc();
1741 int ret=0;
1742
1743 if (namelen == 0)
1744 return(ENOTSUP);
1745
1746 ret = suser(kauth_cred_get(), &p->p_acflag);
1747 #if KPERF
1748 /* Non-root processes may be blessed by kperf to access data
1749 * logged into trace.
1750 */
1751 if (ret)
1752 ret = kperf_access_check();
1753 #endif /* KPERF */
1754 if (ret)
1755 return(ret);
1756
1757 switch(name[0]) {
1758 case KERN_KDEFLAGS:
1759 case KERN_KDDFLAGS:
1760 case KERN_KDENABLE:
1761 case KERN_KDGETBUF:
1762 case KERN_KDSETUP:
1763 case KERN_KDREMOVE:
1764 case KERN_KDSETREG:
1765 case KERN_KDGETREG:
1766 case KERN_KDREADTR:
1767 case KERN_KDWRITETR:
1768 case KERN_KDWRITEMAP:
1769 case KERN_KDPIDTR:
1770 case KERN_KDTHRMAP:
1771 case KERN_KDPIDEX:
1772 case KERN_KDSETRTCDEC:
1773 case KERN_KDSETBUF:
1774 case KERN_KDGETENTROPY:
1775 case KERN_KDENABLE_BG_TRACE:
1776 case KERN_KDDISABLE_BG_TRACE:
1777 case KERN_KDREADCURTHRMAP:
1778 case KERN_KDSET_TYPEFILTER:
1779 case KERN_KDBUFWAIT:
1780 case KERN_KDCPUMAP:
1781
1782 ret = kdbg_control(name, namelen, oldp, oldlenp);
1783 break;
1784 default:
1785 ret= ENOTSUP;
1786 break;
1787 }
1788
1789 /* adjust index so we return the right required/consumed amount */
1790 if (!ret)
1791 req->oldidx += req->oldlen;
1792
1793 return (ret);
1794 }
1795 SYSCTL_PROC(_kern, KERN_KDEBUG, kdebug, CTLTYPE_NODE|CTLFLAG_RD | CTLFLAG_LOCKED,
1796 0, /* Pointer argument (arg1) */
1797 0, /* Integer argument (arg2) */
1798 sysctl_kdebug_ops, /* Handler function */
1799 NULL, /* Data pointer */
1800 "");
1801
1802
1803 /*
1804 * Return the top *sizep bytes of the user stack, or the entire area of the
1805 * user stack down through the saved exec_path, whichever is smaller.
1806 */
1807 STATIC int
1808 sysctl_doprocargs SYSCTL_HANDLER_ARGS
1809 {
1810 __unused int cmd = oidp->oid_arg2; /* subcommand*/
1811 int *name = arg1; /* oid element argument vector */
1812 int namelen = arg2; /* number of oid element arguments */
1813 user_addr_t oldp = req->oldptr; /* user buffer copy out address */
1814 size_t *oldlenp = &req->oldlen; /* user buffer copy out size */
1815 // user_addr_t newp = req->newptr; /* user buffer copy in address */
1816 // size_t newlen = req->newlen; /* user buffer copy in size */
1817 int error;
1818
1819 error = sysctl_procargsx( name, namelen, oldp, oldlenp, current_proc(), 0);
1820
1821 /* adjust index so we return the right required/consumed amount */
1822 if (!error)
1823 req->oldidx += req->oldlen;
1824
1825 return (error);
1826 }
1827 SYSCTL_PROC(_kern, KERN_PROCARGS, procargs, CTLTYPE_NODE|CTLFLAG_RD | CTLFLAG_LOCKED,
1828 0, /* Pointer argument (arg1) */
1829 0, /* Integer argument (arg2) */
1830 sysctl_doprocargs, /* Handler function */
1831 NULL, /* Data pointer */
1832 "");
1833
1834 STATIC int
1835 sysctl_doprocargs2 SYSCTL_HANDLER_ARGS
1836 {
1837 __unused int cmd = oidp->oid_arg2; /* subcommand*/
1838 int *name = arg1; /* oid element argument vector */
1839 int namelen = arg2; /* number of oid element arguments */
1840 user_addr_t oldp = req->oldptr; /* user buffer copy out address */
1841 size_t *oldlenp = &req->oldlen; /* user buffer copy out size */
1842 // user_addr_t newp = req->newptr; /* user buffer copy in address */
1843 // size_t newlen = req->newlen; /* user buffer copy in size */
1844 int error;
1845
1846 error = sysctl_procargsx( name, namelen, oldp, oldlenp, current_proc(), 1);
1847
1848 /* adjust index so we return the right required/consumed amount */
1849 if (!error)
1850 req->oldidx += req->oldlen;
1851
1852 return (error);
1853 }
1854 SYSCTL_PROC(_kern, KERN_PROCARGS2, procargs2, CTLTYPE_NODE|CTLFLAG_RD | CTLFLAG_LOCKED,
1855 0, /* Pointer argument (arg1) */
1856 0, /* Integer argument (arg2) */
1857 sysctl_doprocargs2, /* Handler function */
1858 NULL, /* Data pointer */
1859 "");
1860
1861 STATIC int
1862 sysctl_procargsx(int *name, u_int namelen, user_addr_t where,
1863 size_t *sizep, proc_t cur_proc, int argc_yes)
1864 {
1865 proc_t p;
1866 int buflen = where != USER_ADDR_NULL ? *sizep : 0;
1867 int error = 0;
1868 struct _vm_map *proc_map;
1869 struct task * task;
1870 vm_map_copy_t tmp;
1871 user_addr_t arg_addr;
1872 size_t arg_size;
1873 caddr_t data;
1874 size_t argslen=0;
1875 int size;
1876 vm_offset_t copy_start, copy_end;
1877 kern_return_t ret;
1878 int pid;
1879 kauth_cred_t my_cred;
1880 uid_t uid;
1881
1882 if ( namelen < 1 )
1883 return(EINVAL);
1884
1885 if (argc_yes)
1886 buflen -= sizeof(int); /* reserve first word to return argc */
1887
1888 /* we only care about buflen when where (oldp from sysctl) is not NULL. */
1889 /* when where (oldp from sysctl) is NULL and sizep (oldlenp from sysctl */
1890 /* is not NULL then the caller wants us to return the length needed to */
1891 /* hold the data we would return */
1892 if (where != USER_ADDR_NULL && (buflen <= 0 || buflen > ARG_MAX)) {
1893 return(EINVAL);
1894 }
1895 arg_size = buflen;
1896
1897 /*
1898 * Lookup process by pid
1899 */
1900 pid = name[0];
1901 p = proc_find(pid);
1902 if (p == NULL) {
1903 return(EINVAL);
1904 }
1905
1906 /*
1907 * Copy the top N bytes of the stack.
1908 * On all machines we have so far, the stack grows
1909 * downwards.
1910 *
1911 * If the user expects no more than N bytes of
1912 * argument list, use that as a guess for the
1913 * size.
1914 */
1915
1916 if (!p->user_stack) {
1917 proc_rele(p);
1918 return(EINVAL);
1919 }
1920
1921 if (where == USER_ADDR_NULL) {
1922 /* caller only wants to know length of proc args data */
1923 if (sizep == NULL) {
1924 proc_rele(p);
1925 return(EFAULT);
1926 }
1927
1928 size = p->p_argslen;
1929 proc_rele(p);
1930 if (argc_yes) {
1931 size += sizeof(int);
1932 }
1933 else {
1934 /*
1935 * old PROCARGS will return the executable's path and plus some
1936 * extra space for work alignment and data tags
1937 */
1938 size += PATH_MAX + (6 * sizeof(int));
1939 }
1940 size += (size & (sizeof(int) - 1)) ? (sizeof(int) - (size & (sizeof(int) - 1))) : 0;
1941 *sizep = size;
1942 return (0);
1943 }
1944
1945 my_cred = kauth_cred_proc_ref(p);
1946 uid = kauth_cred_getuid(my_cred);
1947 kauth_cred_unref(&my_cred);
1948
1949 if ((uid != kauth_cred_getuid(kauth_cred_get()))
1950 && suser(kauth_cred_get(), &cur_proc->p_acflag)) {
1951 proc_rele(p);
1952 return (EINVAL);
1953 }
1954
1955 if ((u_int)arg_size > p->p_argslen)
1956 arg_size = round_page(p->p_argslen);
1957
1958 arg_addr = p->user_stack - arg_size;
1959
1960
1961 /*
1962 * Before we can block (any VM code), make another
1963 * reference to the map to keep it alive. We do
1964 * that by getting a reference on the task itself.
1965 */
1966 task = p->task;
1967 if (task == NULL) {
1968 proc_rele(p);
1969 return(EINVAL);
1970 }
1971
1972 argslen = p->p_argslen;
1973 /*
1974 * Once we have a task reference we can convert that into a
1975 * map reference, which we will use in the calls below. The
1976 * task/process may change its map after we take this reference
1977 * (see execve), but the worst that will happen then is a return
1978 * of stale info (which is always a possibility).
1979 */
1980 task_reference(task);
1981 proc_rele(p);
1982 proc_map = get_task_map_reference(task);
1983 task_deallocate(task);
1984
1985 if (proc_map == NULL)
1986 return(EINVAL);
1987
1988
1989 ret = kmem_alloc(kernel_map, &copy_start, round_page(arg_size));
1990 if (ret != KERN_SUCCESS) {
1991 vm_map_deallocate(proc_map);
1992 return(ENOMEM);
1993 }
1994
1995 copy_end = round_page(copy_start + arg_size);
1996
1997 if( vm_map_copyin(proc_map, (vm_map_address_t)arg_addr,
1998 (vm_map_size_t)arg_size, FALSE, &tmp) != KERN_SUCCESS) {
1999 vm_map_deallocate(proc_map);
2000 kmem_free(kernel_map, copy_start,
2001 round_page(arg_size));
2002 return (EIO);
2003 }
2004
2005 /*
2006 * Now that we've done the copyin from the process'
2007 * map, we can release the reference to it.
2008 */
2009 vm_map_deallocate(proc_map);
2010
2011 if( vm_map_copy_overwrite(kernel_map,
2012 (vm_map_address_t)copy_start,
2013 tmp, FALSE) != KERN_SUCCESS) {
2014 kmem_free(kernel_map, copy_start,
2015 round_page(arg_size));
2016 return (EIO);
2017 }
2018
2019 if (arg_size > argslen) {
2020 data = (caddr_t) (copy_end - argslen);
2021 size = argslen;
2022 } else {
2023 data = (caddr_t) (copy_end - arg_size);
2024 size = arg_size;
2025 }
2026
2027 if (argc_yes) {
2028 /* Put processes argc as the first word in the copyout buffer */
2029 suword(where, p->p_argc);
2030 error = copyout(data, (where + sizeof(int)), size);
2031 size += sizeof(int);
2032 } else {
2033 error = copyout(data, where, size);
2034
2035 /*
2036 * Make the old PROCARGS work to return the executable's path
2037 * But, only if there is enough space in the provided buffer
2038 *
2039 * on entry: data [possibily] points to the beginning of the path
2040 *
2041 * Note: we keep all pointers&sizes aligned to word boundries
2042 */
2043 if ( (! error) && (buflen > 0 && (u_int)buflen > argslen) )
2044 {
2045 int binPath_sz, alignedBinPath_sz = 0;
2046 int extraSpaceNeeded, addThis;
2047 user_addr_t placeHere;
2048 char * str = (char *) data;
2049 int max_len = size;
2050
2051 /* Some apps are really bad about messing up their stacks
2052 So, we have to be extra careful about getting the length
2053 of the executing binary. If we encounter an error, we bail.
2054 */
2055
2056 /* Limit ourselves to PATH_MAX paths */
2057 if ( max_len > PATH_MAX ) max_len = PATH_MAX;
2058
2059 binPath_sz = 0;
2060
2061 while ( (binPath_sz < max_len-1) && (*str++ != 0) )
2062 binPath_sz++;
2063
2064 /* If we have a NUL terminator, copy it, too */
2065 if (binPath_sz < max_len-1) binPath_sz += 1;
2066
2067 /* Pre-Flight the space requiremnts */
2068
2069 /* Account for the padding that fills out binPath to the next word */
2070 alignedBinPath_sz += (binPath_sz & (sizeof(int)-1)) ? (sizeof(int)-(binPath_sz & (sizeof(int)-1))) : 0;
2071
2072 placeHere = where + size;
2073
2074 /* Account for the bytes needed to keep placeHere word aligned */
2075 addThis = (placeHere & (sizeof(int)-1)) ? (sizeof(int)-(placeHere & (sizeof(int)-1))) : 0;
2076
2077 /* Add up all the space that is needed */
2078 extraSpaceNeeded = alignedBinPath_sz + addThis + binPath_sz + (4 * sizeof(int));
2079
2080 /* is there is room to tack on argv[0]? */
2081 if ( (buflen & ~(sizeof(int)-1)) >= ( argslen + extraSpaceNeeded ))
2082 {
2083 placeHere += addThis;
2084 suword(placeHere, 0);
2085 placeHere += sizeof(int);
2086 suword(placeHere, 0xBFFF0000);
2087 placeHere += sizeof(int);
2088 suword(placeHere, 0);
2089 placeHere += sizeof(int);
2090 error = copyout(data, placeHere, binPath_sz);
2091 if ( ! error )
2092 {
2093 placeHere += binPath_sz;
2094 suword(placeHere, 0);
2095 size += extraSpaceNeeded;
2096 }
2097 }
2098 }
2099 }
2100
2101 if (copy_start != (vm_offset_t) 0) {
2102 kmem_free(kernel_map, copy_start, copy_end - copy_start);
2103 }
2104 if (error) {
2105 return(error);
2106 }
2107
2108 if (where != USER_ADDR_NULL)
2109 *sizep = size;
2110 return (0);
2111 }
2112
2113
2114 /*
2115 * Max number of concurrent aio requests
2116 */
2117 STATIC int
2118 sysctl_aiomax
2119 (__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
2120 {
2121 int new_value, changed;
2122 int error = sysctl_io_number(req, aio_max_requests, sizeof(int), &new_value, &changed);
2123 if (changed) {
2124 /* make sure the system-wide limit is greater than the per process limit */
2125 if (new_value >= aio_max_requests_per_process && new_value <= AIO_MAX_REQUESTS)
2126 aio_max_requests = new_value;
2127 else
2128 error = EINVAL;
2129 }
2130 return(error);
2131 }
2132
2133
2134 /*
2135 * Max number of concurrent aio requests per process
2136 */
2137 STATIC int
2138 sysctl_aioprocmax
2139 (__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
2140 {
2141 int new_value, changed;
2142 int error = sysctl_io_number(req, aio_max_requests_per_process, sizeof(int), &new_value, &changed);
2143 if (changed) {
2144 /* make sure per process limit is less than the system-wide limit */
2145 if (new_value <= aio_max_requests && new_value >= AIO_LISTIO_MAX)
2146 aio_max_requests_per_process = new_value;
2147 else
2148 error = EINVAL;
2149 }
2150 return(error);
2151 }
2152
2153
2154 /*
2155 * Max number of async IO worker threads
2156 */
2157 STATIC int
2158 sysctl_aiothreads
2159 (__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
2160 {
2161 int new_value, changed;
2162 int error = sysctl_io_number(req, aio_worker_threads, sizeof(int), &new_value, &changed);
2163 if (changed) {
2164 /* we only allow an increase in the number of worker threads */
2165 if (new_value > aio_worker_threads ) {
2166 _aio_create_worker_threads((new_value - aio_worker_threads));
2167 aio_worker_threads = new_value;
2168 }
2169 else
2170 error = EINVAL;
2171 }
2172 return(error);
2173 }
2174
2175
2176 /*
2177 * System-wide limit on the max number of processes
2178 */
2179 STATIC int
2180 sysctl_maxproc
2181 (__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
2182 {
2183 int new_value, changed;
2184 int error = sysctl_io_number(req, maxproc, sizeof(int), &new_value, &changed);
2185 if (changed) {
2186 AUDIT_ARG(value32, new_value);
2187 /* make sure the system-wide limit is less than the configured hard
2188 limit set at kernel compilation */
2189 if (new_value <= hard_maxproc && new_value > 0)
2190 maxproc = new_value;
2191 else
2192 error = EINVAL;
2193 }
2194 return(error);
2195 }
2196
2197 SYSCTL_STRING(_kern, KERN_OSTYPE, ostype,
2198 CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED,
2199 ostype, 0, "");
2200 SYSCTL_STRING(_kern, KERN_OSRELEASE, osrelease,
2201 CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED,
2202 osrelease, 0, "");
2203 SYSCTL_INT(_kern, KERN_OSREV, osrevision,
2204 CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED,
2205 (int *)NULL, BSD, "");
2206 SYSCTL_STRING(_kern, KERN_VERSION, version,
2207 CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED,
2208 version, 0, "");
2209 SYSCTL_STRING(_kern, OID_AUTO, uuid,
2210 CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED,
2211 &kernel_uuid_string[0], 0, "");
2212
2213 #if DEBUG
2214 int debug_kprint_syscall = 0;
2215 char debug_kprint_syscall_process[MAXCOMLEN+1];
2216
2217 /* Thread safe: bits and string value are not used to reclaim state */
2218 SYSCTL_INT (_debug, OID_AUTO, kprint_syscall,
2219 CTLFLAG_RW | CTLFLAG_LOCKED, &debug_kprint_syscall, 0, "kprintf syscall tracing");
2220 SYSCTL_STRING(_debug, OID_AUTO, kprint_syscall_process,
2221 CTLFLAG_RW | CTLFLAG_LOCKED, debug_kprint_syscall_process, sizeof(debug_kprint_syscall_process),
2222 "name of process for kprintf syscall tracing");
2223
2224 int debug_kprint_current_process(const char **namep)
2225 {
2226 struct proc *p = current_proc();
2227
2228 if (p == NULL) {
2229 return 0;
2230 }
2231
2232 if (debug_kprint_syscall_process[0]) {
2233 /* user asked to scope tracing to a particular process name */
2234 if(0 == strncmp(debug_kprint_syscall_process,
2235 p->p_comm, sizeof(debug_kprint_syscall_process))) {
2236 /* no value in telling the user that we traced what they asked */
2237 if(namep) *namep = NULL;
2238
2239 return 1;
2240 } else {
2241 return 0;
2242 }
2243 }
2244
2245 /* trace all processes. Tell user what we traced */
2246 if (namep) {
2247 *namep = p->p_comm;
2248 }
2249
2250 return 1;
2251 }
2252 #endif
2253
2254 /* PR-5293665: need to use a callback function for kern.osversion to set
2255 * osversion in IORegistry */
2256
2257 STATIC int
2258 sysctl_osversion(__unused struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req)
2259 {
2260 int rval = 0;
2261
2262 rval = sysctl_handle_string(oidp, arg1, arg2, req);
2263
2264 if (req->newptr) {
2265 IORegistrySetOSBuildVersion((char *)arg1);
2266 }
2267
2268 return rval;
2269 }
2270
2271 SYSCTL_PROC(_kern, KERN_OSVERSION, osversion,
2272 CTLFLAG_RW | CTLFLAG_KERN | CTLTYPE_STRING | CTLFLAG_LOCKED,
2273 osversion, 256 /* OSVERSIZE*/,
2274 sysctl_osversion, "A", "");
2275
2276 STATIC int
2277 sysctl_sysctl_bootargs
2278 (__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
2279 {
2280 int error;
2281 char buf[256];
2282
2283 strlcpy(buf, PE_boot_args(), 256);
2284 error = sysctl_io_string(req, buf, 256, 0, NULL);
2285 return(error);
2286 }
2287
2288 SYSCTL_PROC(_kern, OID_AUTO, bootargs,
2289 CTLFLAG_LOCKED | CTLFLAG_RD | CTLFLAG_KERN | CTLTYPE_STRING,
2290 NULL, 0,
2291 sysctl_sysctl_bootargs, "A", "bootargs");
2292
2293 SYSCTL_INT(_kern, KERN_MAXFILES, maxfiles,
2294 CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED,
2295 &maxfiles, 0, "");
2296 SYSCTL_INT(_kern, KERN_ARGMAX, argmax,
2297 CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED,
2298 (int *)NULL, ARG_MAX, "");
2299 SYSCTL_INT(_kern, KERN_POSIX1, posix1version,
2300 CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED,
2301 (int *)NULL, _POSIX_VERSION, "");
2302 SYSCTL_INT(_kern, KERN_NGROUPS, ngroups,
2303 CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED,
2304 (int *)NULL, NGROUPS_MAX, "");
2305 SYSCTL_INT(_kern, KERN_JOB_CONTROL, job_control,
2306 CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED,
2307 (int *)NULL, 1, "");
2308 #if 1 /* _POSIX_SAVED_IDS from <unistd.h> */
2309 SYSCTL_INT(_kern, KERN_SAVED_IDS, saved_ids,
2310 CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED,
2311 (int *)NULL, 1, "");
2312 #else
2313 SYSCTL_INT(_kern, KERN_SAVED_IDS, saved_ids,
2314 CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED,
2315 NULL, 0, "");
2316 #endif
2317 SYSCTL_INT(_kern, OID_AUTO, num_files,
2318 CTLFLAG_RD | CTLFLAG_LOCKED,
2319 &nfiles, 0, "");
2320 SYSCTL_COMPAT_INT(_kern, OID_AUTO, num_vnodes,
2321 CTLFLAG_RD | CTLFLAG_LOCKED,
2322 &numvnodes, 0, "");
2323 SYSCTL_INT(_kern, OID_AUTO, num_tasks,
2324 CTLFLAG_RD | CTLFLAG_LOCKED,
2325 &task_max, 0, "");
2326 SYSCTL_INT(_kern, OID_AUTO, num_threads,
2327 CTLFLAG_RD | CTLFLAG_LOCKED,
2328 &thread_max, 0, "");
2329 SYSCTL_INT(_kern, OID_AUTO, num_taskthreads,
2330 CTLFLAG_RD | CTLFLAG_LOCKED,
2331 &task_threadmax, 0, "");
2332
2333 STATIC int
2334 sysctl_maxvnodes (__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
2335 {
2336 int oldval = desiredvnodes;
2337 int error = sysctl_io_number(req, desiredvnodes, sizeof(int), &desiredvnodes, NULL);
2338
2339 if (oldval != desiredvnodes) {
2340 reset_vmobjectcache(oldval, desiredvnodes);
2341 resize_namecache(desiredvnodes);
2342 }
2343
2344 return(error);
2345 }
2346
2347 SYSCTL_INT(_kern, OID_AUTO, namecache_disabled,
2348 CTLFLAG_RW | CTLFLAG_LOCKED,
2349 &nc_disabled, 0, "");
2350
2351 SYSCTL_PROC(_kern, KERN_MAXVNODES, maxvnodes,
2352 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
2353 0, 0, sysctl_maxvnodes, "I", "");
2354
2355 SYSCTL_PROC(_kern, KERN_MAXPROC, maxproc,
2356 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
2357 0, 0, sysctl_maxproc, "I", "");
2358
2359 SYSCTL_PROC(_kern, KERN_AIOMAX, aiomax,
2360 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
2361 0, 0, sysctl_aiomax, "I", "");
2362
2363 SYSCTL_PROC(_kern, KERN_AIOPROCMAX, aioprocmax,
2364 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
2365 0, 0, sysctl_aioprocmax, "I", "");
2366
2367 SYSCTL_PROC(_kern, KERN_AIOTHREADS, aiothreads,
2368 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
2369 0, 0, sysctl_aiothreads, "I", "");
2370
2371 STATIC int
2372 sysctl_securelvl
2373 (__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
2374 {
2375 int new_value, changed;
2376 int error = sysctl_io_number(req, securelevel, sizeof(int), &new_value, &changed);
2377 if (changed) {
2378 if (!(new_value < securelevel && req->p->p_pid != 1)) {
2379 proc_list_lock();
2380 securelevel = new_value;
2381 proc_list_unlock();
2382 } else {
2383 error = EPERM;
2384 }
2385 }
2386 return(error);
2387 }
2388
2389 SYSCTL_PROC(_kern, KERN_SECURELVL, securelevel,
2390 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
2391 0, 0, sysctl_securelvl, "I", "");
2392
2393
2394 STATIC int
2395 sysctl_domainname
2396 (__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
2397 {
2398 int error, changed;
2399 error = sysctl_io_string(req, domainname, sizeof(domainname), 0, &changed);
2400 if (changed) {
2401 domainnamelen = strlen(domainname);
2402 }
2403 return(error);
2404 }
2405
2406 SYSCTL_PROC(_kern, KERN_DOMAINNAME, nisdomainname,
2407 CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_LOCKED,
2408 0, 0, sysctl_domainname, "A", "");
2409
2410 SYSCTL_COMPAT_INT(_kern, KERN_HOSTID, hostid,
2411 CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED,
2412 &hostid, 0, "");
2413
2414 STATIC int
2415 sysctl_hostname
2416 (__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
2417 {
2418 int error, changed;
2419 error = sysctl_io_string(req, hostname, sizeof(hostname), 1, &changed);
2420 if (changed) {
2421 hostnamelen = req->newlen;
2422 }
2423 return(error);
2424 }
2425
2426
2427 SYSCTL_PROC(_kern, KERN_HOSTNAME, hostname,
2428 CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_LOCKED,
2429 0, 0, sysctl_hostname, "A", "");
2430
2431 STATIC int
2432 sysctl_procname
2433 (__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
2434 {
2435 /* Original code allowed writing, I'm copying this, although this all makes
2436 no sense to me. Besides, this sysctl is never used. */
2437 return sysctl_io_string(req, &req->p->p_name[0], (2*MAXCOMLEN+1), 1, NULL);
2438 }
2439
2440 SYSCTL_PROC(_kern, KERN_PROCNAME, procname,
2441 CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_ANYBODY | CTLFLAG_LOCKED,
2442 0, 0, sysctl_procname, "A", "");
2443
2444 SYSCTL_INT(_kern, KERN_SPECULATIVE_READS, speculative_reads_disabled,
2445 CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED,
2446 &speculative_reads_disabled, 0, "");
2447
2448 SYSCTL_INT(_kern, OID_AUTO, ignore_is_ssd,
2449 CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED,
2450 &ignore_is_ssd, 0, "");
2451
2452 SYSCTL_UINT(_kern, OID_AUTO, preheat_pages_max,
2453 CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED,
2454 &preheat_pages_max, 0, "");
2455
2456 SYSCTL_UINT(_kern, OID_AUTO, preheat_pages_min,
2457 CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED,
2458 &preheat_pages_min, 0, "");
2459
2460 SYSCTL_UINT(_kern, OID_AUTO, speculative_prefetch_max,
2461 CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED,
2462 &speculative_prefetch_max, 0, "");
2463
2464 SYSCTL_UINT(_kern, OID_AUTO, speculative_prefetch_max_iosize,
2465 CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED,
2466 &speculative_prefetch_max_iosize, 0, "");
2467
2468 SYSCTL_UINT(_kern, OID_AUTO, vm_page_free_target,
2469 CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED,
2470 &vm_page_free_target, 0, "");
2471
2472 SYSCTL_UINT(_kern, OID_AUTO, vm_page_free_min,
2473 CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED,
2474 &vm_page_free_min, 0, "");
2475
2476 SYSCTL_UINT(_kern, OID_AUTO, vm_page_free_reserved,
2477 CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED,
2478 &vm_page_free_reserved, 0, "");
2479
2480 SYSCTL_UINT(_kern, OID_AUTO, vm_page_speculative_percentage,
2481 CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED,
2482 &vm_page_speculative_percentage, 0, "");
2483
2484 SYSCTL_UINT(_kern, OID_AUTO, vm_page_speculative_q_age_ms,
2485 CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED,
2486 &vm_page_speculative_q_age_ms, 0, "");
2487
2488 SYSCTL_UINT(_kern, OID_AUTO, vm_max_delayed_work_limit,
2489 CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED,
2490 &vm_max_delayed_work_limit, 0, "");
2491
2492 SYSCTL_UINT(_kern, OID_AUTO, vm_max_batch,
2493 CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED,
2494 &vm_max_batch, 0, "");
2495
2496 SYSCTL_STRING(_kern, OID_AUTO, bootsessionuuid,
2497 CTLFLAG_RD | CTLFLAG_LOCKED,
2498 &bootsessionuuid_string, sizeof(bootsessionuuid_string) , "");
2499
2500 STATIC int
2501 sysctl_boottime
2502 (__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
2503 {
2504 time_t tv_sec = boottime_sec();
2505 struct proc *p = req->p;
2506
2507 if (proc_is64bit(p)) {
2508 struct user64_timeval t;
2509 t.tv_sec = tv_sec;
2510 t.tv_usec = 0;
2511 return sysctl_io_opaque(req, &t, sizeof(t), NULL);
2512 } else {
2513 struct user32_timeval t;
2514 t.tv_sec = tv_sec;
2515 t.tv_usec = 0;
2516 return sysctl_io_opaque(req, &t, sizeof(t), NULL);
2517 }
2518 }
2519
2520 SYSCTL_PROC(_kern, KERN_BOOTTIME, boottime,
2521 CTLTYPE_STRUCT | CTLFLAG_RD | CTLFLAG_LOCKED,
2522 0, 0, sysctl_boottime, "S,timeval", "");
2523
2524 STATIC int
2525 sysctl_symfile
2526 (__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
2527 {
2528 char *str;
2529 int error = get_kernel_symfile(req->p, &str);
2530 if (error)
2531 return (error);
2532 return sysctl_io_string(req, str, 0, 0, NULL);
2533 }
2534
2535
2536 SYSCTL_PROC(_kern, KERN_SYMFILE, symfile,
2537 CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_LOCKED,
2538 0, 0, sysctl_symfile, "A", "");
2539
2540 #if NFSCLIENT
2541 STATIC int
2542 sysctl_netboot
2543 (__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
2544 {
2545 return sysctl_io_number(req, netboot_root(), sizeof(int), NULL, NULL);
2546 }
2547
2548 SYSCTL_PROC(_kern, KERN_NETBOOT, netboot,
2549 CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
2550 0, 0, sysctl_netboot, "I", "");
2551 #endif
2552
2553 #ifdef CONFIG_IMGSRC_ACCESS
2554 /*
2555 * Legacy--act as if only one layer of nesting is possible.
2556 */
2557 STATIC int
2558 sysctl_imgsrcdev
2559 (__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
2560 {
2561 vfs_context_t ctx = vfs_context_current();
2562 vnode_t devvp;
2563 int result;
2564
2565 if (!vfs_context_issuser(ctx)) {
2566 return EPERM;
2567 }
2568
2569 if (imgsrc_rootvnodes[0] == NULL) {
2570 return ENOENT;
2571 }
2572
2573 result = vnode_getwithref(imgsrc_rootvnodes[0]);
2574 if (result != 0) {
2575 return result;
2576 }
2577
2578 devvp = vnode_mount(imgsrc_rootvnodes[0])->mnt_devvp;
2579 result = vnode_getwithref(devvp);
2580 if (result != 0) {
2581 goto out;
2582 }
2583
2584 result = sysctl_io_number(req, vnode_specrdev(devvp), sizeof(dev_t), NULL, NULL);
2585
2586 vnode_put(devvp);
2587 out:
2588 vnode_put(imgsrc_rootvnodes[0]);
2589 return result;
2590 }
2591
2592 SYSCTL_PROC(_kern, OID_AUTO, imgsrcdev,
2593 CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
2594 0, 0, sysctl_imgsrcdev, "I", "");
2595
2596 STATIC int
2597 sysctl_imgsrcinfo
2598 (__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
2599 {
2600 int error;
2601 struct imgsrc_info info[MAX_IMAGEBOOT_NESTING]; /* 2 for now, no problem */
2602 uint32_t i;
2603 vnode_t rvp, devvp;
2604
2605 if (imgsrc_rootvnodes[0] == NULLVP) {
2606 return ENXIO;
2607 }
2608
2609 for (i = 0; i < MAX_IMAGEBOOT_NESTING; i++) {
2610 /*
2611 * Go get the root vnode.
2612 */
2613 rvp = imgsrc_rootvnodes[i];
2614 if (rvp == NULLVP) {
2615 break;
2616 }
2617
2618 error = vnode_get(rvp);
2619 if (error != 0) {
2620 return error;
2621 }
2622
2623 /*
2624 * For now, no getting at a non-local volume.
2625 */
2626 devvp = vnode_mount(rvp)->mnt_devvp;
2627 if (devvp == NULL) {
2628 vnode_put(rvp);
2629 return EINVAL;
2630 }
2631
2632 error = vnode_getwithref(devvp);
2633 if (error != 0) {
2634 vnode_put(rvp);
2635 return error;
2636 }
2637
2638 /*
2639 * Fill in info.
2640 */
2641 info[i].ii_dev = vnode_specrdev(devvp);
2642 info[i].ii_flags = 0;
2643 info[i].ii_height = i;
2644 bzero(info[i].ii_reserved, sizeof(info[i].ii_reserved));
2645
2646 vnode_put(devvp);
2647 vnode_put(rvp);
2648 }
2649
2650 return sysctl_io_opaque(req, info, i * sizeof(info[0]), NULL);
2651 }
2652
2653 SYSCTL_PROC(_kern, OID_AUTO, imgsrcinfo,
2654 CTLTYPE_OPAQUE | CTLFLAG_RD | CTLFLAG_LOCKED,
2655 0, 0, sysctl_imgsrcinfo, "I", "");
2656
2657 #endif /* CONFIG_IMGSRC_ACCESS */
2658
2659
2660 SYSCTL_DECL(_kern_timer);
2661 SYSCTL_NODE(_kern, OID_AUTO, timer, CTLFLAG_RW | CTLFLAG_LOCKED, 0, "timer");
2662
2663 SYSCTL_INT(_kern_timer, OID_AUTO, coalescing_enabled,
2664 CTLFLAG_KERN | CTLFLAG_RW | CTLFLAG_LOCKED,
2665 &mach_timer_coalescing_enabled, 0, "");
2666
2667 SYSCTL_QUAD(_kern_timer, OID_AUTO, deadline_tracking_bin_1,
2668 CTLFLAG_RW | CTLFLAG_LOCKED,
2669 &timer_deadline_tracking_bin_1, "");
2670 SYSCTL_QUAD(_kern_timer, OID_AUTO, deadline_tracking_bin_2,
2671 CTLFLAG_RW | CTLFLAG_LOCKED,
2672 &timer_deadline_tracking_bin_2, "");
2673
2674 SYSCTL_DECL(_kern_timer_longterm);
2675 SYSCTL_NODE(_kern_timer, OID_AUTO, longterm, CTLFLAG_RW | CTLFLAG_LOCKED, 0, "longterm");
2676
2677 /* Must match definition in osfmk/kern/timer_call.c */
2678 enum {
2679 THRESHOLD, QCOUNT,
2680 ENQUEUES, DEQUEUES, ESCALATES, SCANS, PREEMPTS,
2681 LATENCY, LATENCY_MIN, LATENCY_MAX
2682 };
2683 extern uint64_t timer_sysctl_get(int);
2684 extern int timer_sysctl_set(int, uint64_t);
2685
2686 STATIC int
2687 sysctl_timer
2688 (__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
2689 {
2690 int oid = (int)arg1;
2691 uint64_t value = timer_sysctl_get(oid);
2692 uint64_t new_value;
2693 int error;
2694 int changed;
2695
2696 error = sysctl_io_number(req, value, sizeof(value), &new_value, &changed);
2697 if (changed)
2698 error = timer_sysctl_set(oid, new_value);
2699
2700 return error;
2701 }
2702
2703 SYSCTL_PROC(_kern_timer_longterm, OID_AUTO, threshold,
2704 CTLTYPE_QUAD | CTLFLAG_RW | CTLFLAG_LOCKED,
2705 (void *) THRESHOLD, 0, sysctl_timer, "Q", "");
2706 SYSCTL_PROC(_kern_timer_longterm, OID_AUTO, qlen,
2707 CTLTYPE_QUAD | CTLFLAG_RD | CTLFLAG_LOCKED,
2708 (void *) QCOUNT, 0, sysctl_timer, "Q", "");
2709 #if DEBUG
2710 SYSCTL_PROC(_kern_timer_longterm, OID_AUTO, enqueues,
2711 CTLTYPE_QUAD | CTLFLAG_RD | CTLFLAG_LOCKED,
2712 (void *) ENQUEUES, 0, sysctl_timer, "Q", "");
2713 SYSCTL_PROC(_kern_timer_longterm, OID_AUTO, dequeues,
2714 CTLTYPE_QUAD | CTLFLAG_RD | CTLFLAG_LOCKED,
2715 (void *) DEQUEUES, 0, sysctl_timer, "Q", "");
2716 SYSCTL_PROC(_kern_timer_longterm, OID_AUTO, escalates,
2717 CTLTYPE_QUAD | CTLFLAG_RD | CTLFLAG_LOCKED,
2718 (void *) ESCALATES, 0, sysctl_timer, "Q", "");
2719 SYSCTL_PROC(_kern_timer_longterm, OID_AUTO, scans,
2720 CTLTYPE_QUAD | CTLFLAG_RD | CTLFLAG_LOCKED,
2721 (void *) SCANS, 0, sysctl_timer, "Q", "");
2722 SYSCTL_PROC(_kern_timer_longterm, OID_AUTO, preempts,
2723 CTLTYPE_QUAD | CTLFLAG_RD | CTLFLAG_LOCKED,
2724 (void *) PREEMPTS, 0, sysctl_timer, "Q", "");
2725 SYSCTL_PROC(_kern_timer_longterm, OID_AUTO, latency,
2726 CTLTYPE_QUAD | CTLFLAG_RD | CTLFLAG_LOCKED,
2727 (void *) LATENCY, 0, sysctl_timer, "Q", "");
2728 SYSCTL_PROC(_kern_timer_longterm, OID_AUTO, latency_min,
2729 CTLTYPE_QUAD | CTLFLAG_RD | CTLFLAG_LOCKED,
2730 (void *) LATENCY_MIN, 0, sysctl_timer, "Q", "");
2731 SYSCTL_PROC(_kern_timer_longterm, OID_AUTO, latency_max,
2732 CTLTYPE_QUAD | CTLFLAG_RD | CTLFLAG_LOCKED,
2733 (void *) LATENCY_MAX, 0, sysctl_timer, "Q", "");
2734 #endif /* DEBUG */
2735
2736 STATIC int
2737 sysctl_usrstack
2738 (__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
2739 {
2740 return sysctl_io_number(req, (int)req->p->user_stack, sizeof(int), NULL, NULL);
2741 }
2742
2743 SYSCTL_PROC(_kern, KERN_USRSTACK32, usrstack,
2744 CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
2745 0, 0, sysctl_usrstack, "I", "");
2746
2747 STATIC int
2748 sysctl_usrstack64
2749 (__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
2750 {
2751 return sysctl_io_number(req, req->p->user_stack, sizeof(req->p->user_stack), NULL, NULL);
2752 }
2753
2754 SYSCTL_PROC(_kern, KERN_USRSTACK64, usrstack64,
2755 CTLTYPE_QUAD | CTLFLAG_RD | CTLFLAG_LOCKED,
2756 0, 0, sysctl_usrstack64, "Q", "");
2757
2758 SYSCTL_STRING(_kern, KERN_COREFILE, corefile,
2759 CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED,
2760 corefilename, sizeof(corefilename), "");
2761
2762 STATIC int
2763 sysctl_coredump
2764 (__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
2765 {
2766 #ifdef SECURE_KERNEL
2767 return (ENOTSUP);
2768 #endif
2769 int new_value, changed;
2770 int error = sysctl_io_number(req, do_coredump, sizeof(int), &new_value, &changed);
2771 if (changed) {
2772 if ((new_value == 0) || (new_value == 1))
2773 do_coredump = new_value;
2774 else
2775 error = EINVAL;
2776 }
2777 return(error);
2778 }
2779
2780 SYSCTL_PROC(_kern, KERN_COREDUMP, coredump,
2781 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
2782 0, 0, sysctl_coredump, "I", "");
2783
2784 STATIC int
2785 sysctl_suid_coredump
2786 (__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
2787 {
2788 #ifdef SECURE_KERNEL
2789 return (ENOTSUP);
2790 #endif
2791 int new_value, changed;
2792 int error = sysctl_io_number(req, sugid_coredump, sizeof(int), &new_value, &changed);
2793 if (changed) {
2794 if ((new_value == 0) || (new_value == 1))
2795 sugid_coredump = new_value;
2796 else
2797 error = EINVAL;
2798 }
2799 return(error);
2800 }
2801
2802 SYSCTL_PROC(_kern, KERN_SUGID_COREDUMP, sugid_coredump,
2803 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
2804 0, 0, sysctl_suid_coredump, "I", "");
2805
2806 STATIC int
2807 sysctl_delayterm
2808 (__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
2809 {
2810 struct proc *p = req->p;
2811 int new_value, changed;
2812 int error = sysctl_io_number(req, (req->p->p_lflag & P_LDELAYTERM)? 1: 0, sizeof(int), &new_value, &changed);
2813 if (changed) {
2814 proc_lock(p);
2815 if (new_value)
2816 req->p->p_lflag |= P_LDELAYTERM;
2817 else
2818 req->p->p_lflag &= ~P_LDELAYTERM;
2819 proc_unlock(p);
2820 }
2821 return(error);
2822 }
2823
2824 SYSCTL_PROC(_kern, KERN_PROCDELAYTERM, delayterm,
2825 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
2826 0, 0, sysctl_delayterm, "I", "");
2827
2828
2829 STATIC int
2830 sysctl_rage_vnode
2831 (__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
2832 {
2833 struct proc *p = req->p;
2834 struct uthread *ut;
2835 int new_value, old_value, changed;
2836 int error;
2837
2838 ut = get_bsdthread_info(current_thread());
2839
2840 if (ut->uu_flag & UT_RAGE_VNODES)
2841 old_value = KERN_RAGE_THREAD;
2842 else if (p->p_lflag & P_LRAGE_VNODES)
2843 old_value = KERN_RAGE_PROC;
2844 else
2845 old_value = 0;
2846
2847 error = sysctl_io_number(req, old_value, sizeof(int), &new_value, &changed);
2848
2849 if (error == 0) {
2850 switch (new_value) {
2851 case KERN_RAGE_PROC:
2852 proc_lock(p);
2853 p->p_lflag |= P_LRAGE_VNODES;
2854 proc_unlock(p);
2855 break;
2856 case KERN_UNRAGE_PROC:
2857 proc_lock(p);
2858 p->p_lflag &= ~P_LRAGE_VNODES;
2859 proc_unlock(p);
2860 break;
2861
2862 case KERN_RAGE_THREAD:
2863 ut->uu_flag |= UT_RAGE_VNODES;
2864 break;
2865 case KERN_UNRAGE_THREAD:
2866 ut = get_bsdthread_info(current_thread());
2867 ut->uu_flag &= ~UT_RAGE_VNODES;
2868 break;
2869 }
2870 }
2871 return(error);
2872 }
2873
2874 SYSCTL_PROC(_kern, KERN_RAGEVNODE, rage_vnode,
2875 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY | CTLFLAG_LOCKED,
2876 0, 0, sysctl_rage_vnode, "I", "");
2877
2878 /* XXX move this interface into libproc and remove this sysctl */
2879 STATIC int
2880 sysctl_setthread_cpupercent
2881 (__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
2882 {
2883 int new_value, old_value;
2884 int error = 0;
2885 kern_return_t kret = KERN_SUCCESS;
2886 uint8_t percent = 0;
2887 int ms_refill = 0;
2888
2889 if (!req->newptr)
2890 return (0);
2891
2892 old_value = 0;
2893
2894 if ((error = sysctl_io_number(req, old_value, sizeof(old_value), &new_value, NULL)) != 0)
2895 return (error);
2896
2897 percent = new_value & 0xff; /* low 8 bytes for perent */
2898 ms_refill = (new_value >> 8) & 0xffffff; /* upper 24bytes represent ms refill value */
2899 if (percent > 100)
2900 return (EINVAL);
2901
2902 /*
2903 * If the caller is specifying a percentage of 0, this will unset the CPU limit, if present.
2904 */
2905 if ((kret = thread_set_cpulimit(THREAD_CPULIMIT_BLOCK, percent, ms_refill * (int)NSEC_PER_MSEC)) != 0)
2906 return (EIO);
2907
2908 return (0);
2909 }
2910
2911 SYSCTL_PROC(_kern, OID_AUTO, setthread_cpupercent,
2912 CTLTYPE_INT | CTLFLAG_WR | CTLFLAG_ANYBODY,
2913 0, 0, sysctl_setthread_cpupercent, "I", "set thread cpu percentage limit");
2914
2915
2916 STATIC int
2917 sysctl_kern_check_openevt
2918 (__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
2919 {
2920 struct proc *p = req->p;
2921 int new_value, old_value, changed;
2922 int error;
2923
2924 if (p->p_flag & P_CHECKOPENEVT) {
2925 old_value = KERN_OPENEVT_PROC;
2926 } else {
2927 old_value = 0;
2928 }
2929
2930 error = sysctl_io_number(req, old_value, sizeof(int), &new_value, &changed);
2931
2932 if (error == 0) {
2933 switch (new_value) {
2934 case KERN_OPENEVT_PROC:
2935 OSBitOrAtomic(P_CHECKOPENEVT, &p->p_flag);
2936 break;
2937
2938 case KERN_UNOPENEVT_PROC:
2939 OSBitAndAtomic(~((uint32_t)P_CHECKOPENEVT), &p->p_flag);
2940 break;
2941
2942 default:
2943 error = EINVAL;
2944 }
2945 }
2946 return(error);
2947 }
2948
2949 SYSCTL_PROC(_kern, KERN_CHECKOPENEVT, check_openevt, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY | CTLFLAG_LOCKED,
2950 0, 0, sysctl_kern_check_openevt, "I", "set the per-process check-open-evt flag");
2951
2952
2953
2954 STATIC int
2955 sysctl_nx
2956 (__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
2957 {
2958 #ifdef SECURE_KERNEL
2959 return ENOTSUP;
2960 #endif
2961 int new_value, changed;
2962 int error;
2963
2964 error = sysctl_io_number(req, nx_enabled, sizeof(nx_enabled), &new_value, &changed);
2965 if (error)
2966 return error;
2967
2968 if (changed) {
2969 #if defined(__i386__) || defined(__x86_64__)
2970 /*
2971 * Only allow setting if NX is supported on the chip
2972 */
2973 if (!(cpuid_extfeatures() & CPUID_EXTFEATURE_XD))
2974 return ENOTSUP;
2975 #endif
2976 nx_enabled = new_value;
2977 }
2978 return(error);
2979 }
2980
2981
2982
2983 SYSCTL_PROC(_kern, KERN_NX_PROTECTION, nx,
2984 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED,
2985 0, 0, sysctl_nx, "I", "");
2986
2987 STATIC int
2988 sysctl_loadavg
2989 (__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
2990 {
2991 if (proc_is64bit(req->p)) {
2992 struct user64_loadavg loadinfo64;
2993 fill_loadavg64(&averunnable, &loadinfo64);
2994 return sysctl_io_opaque(req, &loadinfo64, sizeof(loadinfo64), NULL);
2995 } else {
2996 struct user32_loadavg loadinfo32;
2997 fill_loadavg32(&averunnable, &loadinfo32);
2998 return sysctl_io_opaque(req, &loadinfo32, sizeof(loadinfo32), NULL);
2999 }
3000 }
3001
3002 SYSCTL_PROC(_vm, VM_LOADAVG, loadavg,
3003 CTLTYPE_STRUCT | CTLFLAG_RD | CTLFLAG_LOCKED,
3004 0, 0, sysctl_loadavg, "S,loadavg", "");
3005
3006 /*
3007 * Note: Thread safe; vm_map_lock protects in vm_toggle_entry_reuse()
3008 */
3009 STATIC int
3010 sysctl_vm_toggle_address_reuse(__unused struct sysctl_oid *oidp, __unused void *arg1,
3011 __unused int arg2, struct sysctl_req *req)
3012 {
3013 int old_value=0, new_value=0, error=0;
3014
3015 if(vm_toggle_entry_reuse( VM_TOGGLE_GETVALUE, &old_value ))
3016 return(error);
3017 error = sysctl_io_number(req, old_value, sizeof(int), &new_value, NULL);
3018 if (!error) {
3019 return (vm_toggle_entry_reuse(new_value, NULL));
3020 }
3021 return(error);
3022 }
3023
3024 SYSCTL_PROC(_debug, OID_AUTO, toggle_address_reuse, CTLFLAG_ANYBODY | CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED, 0, 0, sysctl_vm_toggle_address_reuse,"I","");
3025
3026 STATIC int
3027 sysctl_swapusage
3028 (__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
3029 {
3030 int error;
3031 uint64_t swap_total;
3032 uint64_t swap_avail;
3033 vm_size_t swap_pagesize;
3034 boolean_t swap_encrypted;
3035 struct xsw_usage xsu;
3036
3037 error = macx_swapinfo(&swap_total,
3038 &swap_avail,
3039 &swap_pagesize,
3040 &swap_encrypted);
3041 if (error)
3042 return error;
3043
3044 xsu.xsu_total = swap_total;
3045 xsu.xsu_avail = swap_avail;
3046 xsu.xsu_used = swap_total - swap_avail;
3047 xsu.xsu_pagesize = swap_pagesize;
3048 xsu.xsu_encrypted = swap_encrypted;
3049 return sysctl_io_opaque(req, &xsu, sizeof(xsu), NULL);
3050 }
3051
3052
3053
3054 SYSCTL_PROC(_vm, VM_SWAPUSAGE, swapusage,
3055 CTLTYPE_STRUCT | CTLFLAG_RD | CTLFLAG_LOCKED,
3056 0, 0, sysctl_swapusage, "S,xsw_usage", "");
3057
3058 #if CONFIG_FREEZE
3059 extern void vm_page_reactivate_all_throttled(void);
3060
3061 static int
3062 sysctl_freeze_enabled SYSCTL_HANDLER_ARGS
3063 {
3064 #pragma unused(arg1, arg2)
3065 int error, val = memorystatus_freeze_enabled ? 1 : 0;
3066 boolean_t disabled;
3067
3068 error = sysctl_handle_int(oidp, &val, 0, req);
3069 if (error || !req->newptr)
3070 return (error);
3071
3072 if (COMPRESSED_PAGER_IS_ACTIVE || DEFAULT_FREEZER_COMPRESSED_PAGER_IS_ACTIVE) {
3073 //assert(req->newptr);
3074 printf("Failed this request to set the sysctl\n");
3075 return EINVAL;
3076 }
3077
3078 /*
3079 * If freeze is being disabled, we need to move dirty pages out from the throttle to the active queue.
3080 */
3081 disabled = (!val && memorystatus_freeze_enabled);
3082
3083 memorystatus_freeze_enabled = val ? TRUE : FALSE;
3084
3085 if (disabled) {
3086 vm_page_reactivate_all_throttled();
3087 }
3088
3089 return (0);
3090 }
3091
3092 SYSCTL_PROC(_vm, OID_AUTO, freeze_enabled, CTLTYPE_INT|CTLFLAG_RW, &memorystatus_freeze_enabled, 0, sysctl_freeze_enabled, "I", "");
3093 #endif /* CONFIG_FREEZE */
3094
3095 /* this kernel does NOT implement shared_region_make_private_np() */
3096 SYSCTL_INT(_kern, KERN_SHREG_PRIVATIZABLE, shreg_private,
3097 CTLFLAG_RD | CTLFLAG_LOCKED,
3098 (int *)NULL, 0, "");
3099
3100 #if defined(__i386__) || defined(__x86_64__)
3101 STATIC int
3102 sysctl_sysctl_exec_affinity(__unused struct sysctl_oid *oidp,
3103 __unused void *arg1, __unused int arg2,
3104 struct sysctl_req *req)
3105 {
3106 proc_t cur_proc = req->p;
3107 int error;
3108
3109 if (req->oldptr != USER_ADDR_NULL) {
3110 cpu_type_t oldcputype = (cur_proc->p_flag & P_AFFINITY) ? CPU_TYPE_POWERPC : CPU_TYPE_I386;
3111 if ((error = SYSCTL_OUT(req, &oldcputype, sizeof(oldcputype))))
3112 return error;
3113 }
3114
3115 if (req->newptr != USER_ADDR_NULL) {
3116 cpu_type_t newcputype;
3117 if ((error = SYSCTL_IN(req, &newcputype, sizeof(newcputype))))
3118 return error;
3119 if (newcputype == CPU_TYPE_I386)
3120 OSBitAndAtomic(~((uint32_t)P_AFFINITY), &cur_proc->p_flag);
3121 else if (newcputype == CPU_TYPE_POWERPC)
3122 OSBitOrAtomic(P_AFFINITY, &cur_proc->p_flag);
3123 else
3124 return (EINVAL);
3125 }
3126
3127 return 0;
3128 }
3129 SYSCTL_PROC(_sysctl, OID_AUTO, proc_exec_affinity, CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY | CTLFLAG_LOCKED, 0, 0, sysctl_sysctl_exec_affinity ,"I","proc_exec_affinity");
3130 #endif
3131
3132 STATIC int
3133 fetch_process_cputype(
3134 proc_t cur_proc,
3135 int *name,
3136 u_int namelen,
3137 cpu_type_t *cputype)
3138 {
3139 proc_t p = PROC_NULL;
3140 int refheld = 0;
3141 cpu_type_t ret = 0;
3142 int error = 0;
3143
3144 if (namelen == 0)
3145 p = cur_proc;
3146 else if (namelen == 1) {
3147 p = proc_find(name[0]);
3148 if (p == NULL)
3149 return (EINVAL);
3150 refheld = 1;
3151 } else {
3152 error = EINVAL;
3153 goto out;
3154 }
3155
3156 #if defined(__i386__) || defined(__x86_64__)
3157 if (p->p_flag & P_TRANSLATED) {
3158 ret = CPU_TYPE_POWERPC;
3159 }
3160 else
3161 #endif
3162 {
3163 ret = cpu_type() & ~CPU_ARCH_MASK;
3164 if (IS_64BIT_PROCESS(p))
3165 ret |= CPU_ARCH_ABI64;
3166 }
3167 *cputype = ret;
3168
3169 if (refheld != 0)
3170 proc_rele(p);
3171 out:
3172 return (error);
3173 }
3174
3175 STATIC int
3176 sysctl_sysctl_native(__unused struct sysctl_oid *oidp, void *arg1, int arg2,
3177 struct sysctl_req *req)
3178 {
3179 int error;
3180 cpu_type_t proc_cputype = 0;
3181 if ((error = fetch_process_cputype(req->p, (int *)arg1, arg2, &proc_cputype)) != 0)
3182 return error;
3183 int res = 1;
3184 if ((proc_cputype & ~CPU_ARCH_MASK) != (cpu_type() & ~CPU_ARCH_MASK))
3185 res = 0;
3186 return SYSCTL_OUT(req, &res, sizeof(res));
3187 }
3188 SYSCTL_PROC(_sysctl, OID_AUTO, proc_native, CTLTYPE_NODE|CTLFLAG_RD | CTLFLAG_LOCKED, 0, 0, sysctl_sysctl_native ,"I","proc_native");
3189
3190 STATIC int
3191 sysctl_sysctl_cputype(__unused struct sysctl_oid *oidp, void *arg1, int arg2,
3192 struct sysctl_req *req)
3193 {
3194 int error;
3195 cpu_type_t proc_cputype = 0;
3196 if ((error = fetch_process_cputype(req->p, (int *)arg1, arg2, &proc_cputype)) != 0)
3197 return error;
3198 return SYSCTL_OUT(req, &proc_cputype, sizeof(proc_cputype));
3199 }
3200 SYSCTL_PROC(_sysctl, OID_AUTO, proc_cputype, CTLTYPE_NODE|CTLFLAG_RD | CTLFLAG_LOCKED, 0, 0, sysctl_sysctl_cputype ,"I","proc_cputype");
3201
3202 STATIC int
3203 sysctl_safeboot
3204 (__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
3205 {
3206 return sysctl_io_number(req, boothowto & RB_SAFEBOOT ? 1 : 0, sizeof(int), NULL, NULL);
3207 }
3208
3209 SYSCTL_PROC(_kern, KERN_SAFEBOOT, safeboot,
3210 CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
3211 0, 0, sysctl_safeboot, "I", "");
3212
3213 STATIC int
3214 sysctl_singleuser
3215 (__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
3216 {
3217 return sysctl_io_number(req, boothowto & RB_SINGLE ? 1 : 0, sizeof(int), NULL, NULL);
3218 }
3219
3220 SYSCTL_PROC(_kern, OID_AUTO, singleuser,
3221 CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
3222 0, 0, sysctl_singleuser, "I", "");
3223
3224 /*
3225 * Controls for debugging affinity sets - see osfmk/kern/affinity.c
3226 */
3227 extern boolean_t affinity_sets_enabled;
3228 extern int affinity_sets_mapping;
3229
3230 SYSCTL_INT (_kern, OID_AUTO, affinity_sets_enabled,
3231 CTLFLAG_RW | CTLFLAG_LOCKED, (int *) &affinity_sets_enabled, 0, "hinting enabled");
3232 SYSCTL_INT (_kern, OID_AUTO, affinity_sets_mapping,
3233 CTLFLAG_RW | CTLFLAG_LOCKED, &affinity_sets_mapping, 0, "mapping policy");
3234
3235 /*
3236 * Boolean indicating if KASLR is active.
3237 */
3238 STATIC int
3239 sysctl_slide
3240 (__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
3241 {
3242 uint32_t slide;
3243
3244 slide = vm_kernel_slide ? 1 : 0;
3245
3246 return sysctl_io_number( req, slide, sizeof(int), NULL, NULL);
3247 }
3248
3249 SYSCTL_PROC(_kern, OID_AUTO, slide,
3250 CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
3251 0, 0, sysctl_slide, "I", "");
3252
3253 /*
3254 * Limit on total memory users can wire.
3255 *
3256 * vm_global_user_wire_limit - system wide limit on wired memory from all processes combined.
3257 *
3258 * vm_user_wire_limit - per address space limit on wired memory. This puts a cap on the process's rlimit value.
3259 *
3260 * These values are initialized to reasonable defaults at boot time based on the available physical memory in
3261 * kmem_init().
3262 *
3263 * All values are in bytes.
3264 */
3265
3266 vm_map_size_t vm_global_no_user_wire_amount;
3267 vm_map_size_t vm_global_user_wire_limit;
3268 vm_map_size_t vm_user_wire_limit;
3269
3270 /*
3271 * There needs to be a more automatic/elegant way to do this
3272 */
3273 SYSCTL_QUAD(_vm, OID_AUTO, global_no_user_wire_amount, CTLFLAG_RW | CTLFLAG_LOCKED, &vm_global_no_user_wire_amount, "");
3274 SYSCTL_QUAD(_vm, OID_AUTO, global_user_wire_limit, CTLFLAG_RW | CTLFLAG_LOCKED, &vm_global_user_wire_limit, "");
3275 SYSCTL_QUAD(_vm, OID_AUTO, user_wire_limit, CTLFLAG_RW | CTLFLAG_LOCKED, &vm_user_wire_limit, "");
3276
3277 extern int vm_map_copy_overwrite_aligned_src_not_internal;
3278 extern int vm_map_copy_overwrite_aligned_src_not_symmetric;
3279 extern int vm_map_copy_overwrite_aligned_src_large;
3280 SYSCTL_INT(_vm, OID_AUTO, vm_copy_src_not_internal, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_map_copy_overwrite_aligned_src_not_internal, 0, "");
3281 SYSCTL_INT(_vm, OID_AUTO, vm_copy_src_not_symmetric, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_map_copy_overwrite_aligned_src_not_symmetric, 0, "");
3282 SYSCTL_INT(_vm, OID_AUTO, vm_copy_src_large, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_map_copy_overwrite_aligned_src_large, 0, "");
3283
3284
3285 extern uint32_t vm_page_external_count;
3286 extern uint32_t vm_page_filecache_min;
3287
3288 SYSCTL_INT(_vm, OID_AUTO, vm_page_external_count, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_page_external_count, 0, "");
3289 SYSCTL_INT(_vm, OID_AUTO, vm_page_filecache_min, CTLFLAG_RW | CTLFLAG_LOCKED, &vm_page_filecache_min, 0, "");
3290
3291 extern int vm_compressor_mode;
3292 extern uint32_t swapout_target_age;
3293 extern int64_t compressor_bytes_used;
3294 extern uint32_t compressor_eval_period_in_msecs;
3295 extern uint32_t compressor_sample_min_in_msecs;
3296 extern uint32_t compressor_sample_max_in_msecs;
3297 extern uint32_t compressor_thrashing_threshold_per_10msecs;
3298 extern uint32_t compressor_thrashing_min_per_10msecs;
3299 extern uint32_t vm_compressor_minorcompact_threshold_divisor;
3300 extern uint32_t vm_compressor_majorcompact_threshold_divisor;
3301 extern uint32_t vm_compressor_unthrottle_threshold_divisor;
3302 extern uint32_t vm_compressor_catchup_threshold_divisor;
3303
3304 SYSCTL_INT(_vm, OID_AUTO, compressor_mode, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_compressor_mode, 0, "");
3305 SYSCTL_QUAD(_vm, OID_AUTO, compressor_bytes_used, CTLFLAG_RD | CTLFLAG_LOCKED, &compressor_bytes_used, "");
3306 SYSCTL_INT(_vm, OID_AUTO, compressor_swapout_target_age, CTLFLAG_RD | CTLFLAG_LOCKED, &swapout_target_age, 0, "");
3307
3308 SYSCTL_INT(_vm, OID_AUTO, compressor_eval_period_in_msecs, CTLFLAG_RW | CTLFLAG_LOCKED, &compressor_eval_period_in_msecs, 0, "");
3309 SYSCTL_INT(_vm, OID_AUTO, compressor_sample_min_in_msecs, CTLFLAG_RW | CTLFLAG_LOCKED, &compressor_sample_min_in_msecs, 0, "");
3310 SYSCTL_INT(_vm, OID_AUTO, compressor_sample_max_in_msecs, CTLFLAG_RW | CTLFLAG_LOCKED, &compressor_sample_max_in_msecs, 0, "");
3311 SYSCTL_INT(_vm, OID_AUTO, compressor_thrashing_threshold_per_10msecs, CTLFLAG_RW | CTLFLAG_LOCKED, &compressor_thrashing_threshold_per_10msecs, 0, "");
3312 SYSCTL_INT(_vm, OID_AUTO, compressor_thrashing_min_per_10msecs, CTLFLAG_RW | CTLFLAG_LOCKED, &compressor_thrashing_min_per_10msecs, 0, "");
3313 SYSCTL_INT(_vm, OID_AUTO, compressor_minorcompact_threshold_divisor, CTLFLAG_RW | CTLFLAG_LOCKED, &vm_compressor_minorcompact_threshold_divisor, 0, "");
3314 SYSCTL_INT(_vm, OID_AUTO, compressor_majorcompact_threshold_divisor, CTLFLAG_RW | CTLFLAG_LOCKED, &vm_compressor_majorcompact_threshold_divisor, 0, "");
3315 SYSCTL_INT(_vm, OID_AUTO, compressor_unthrottle_threshold_divisor, CTLFLAG_RW | CTLFLAG_LOCKED, &vm_compressor_unthrottle_threshold_divisor, 0, "");
3316 SYSCTL_INT(_vm, OID_AUTO, compressor_catchup_threshold_divisor, CTLFLAG_RW | CTLFLAG_LOCKED, &vm_compressor_catchup_threshold_divisor, 0, "");
3317
3318 /*
3319 * enable back trace events for thread blocks
3320 */
3321
3322 extern uint32_t kdebug_thread_block;
3323
3324 SYSCTL_INT (_kern, OID_AUTO, kdebug_thread_block,
3325 CTLFLAG_RW | CTLFLAG_LOCKED, &kdebug_thread_block, 0, "kdebug thread_block");
3326
3327 /*
3328 * Kernel stack size and depth
3329 */
3330 SYSCTL_INT (_kern, OID_AUTO, stack_size,
3331 CTLFLAG_RD | CTLFLAG_LOCKED, (int *) &kernel_stack_size, 0, "Kernel stack size");
3332 SYSCTL_INT (_kern, OID_AUTO, stack_depth_max,
3333 CTLFLAG_RD | CTLFLAG_LOCKED, (int *) &kernel_stack_depth_max, 0, "Max kernel stack depth at interrupt or context switch");
3334
3335 /*
3336 * enable back trace for port allocations
3337 */
3338 extern int ipc_portbt;
3339
3340 SYSCTL_INT(_kern, OID_AUTO, ipc_portbt,
3341 CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED,
3342 &ipc_portbt, 0, "");
3343
3344 /*
3345 * Scheduler sysctls
3346 */
3347
3348 /*
3349 * See osfmk/kern/sched_prim.c for the corresponding definition
3350 * in osfmk/. If either version changes, update the other.
3351 */
3352 #define SCHED_STRING_MAX_LENGTH (48)
3353
3354 extern char sched_string[SCHED_STRING_MAX_LENGTH];
3355 SYSCTL_STRING(_kern, OID_AUTO, sched,
3356 CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED,
3357 sched_string, sizeof(sched_string),
3358 "Timeshare scheduler implementation");
3359
3360 /*
3361 * Only support runtime modification on embedded platforms
3362 * with development config enabled
3363 */