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
155extern sysctlfn net_sysctl;
156extern sysctlfn cpu_sysctl;
157extern int aio_max_requests;
158extern int aio_max_requests_per_process;
159extern int aio_worker_threads;
160extern int lowpri_IO_window_msecs;
161extern int lowpri_IO_delay_msecs;
162extern int nx_enabled;
163extern int speculative_reads_disabled;
164extern int ignore_is_ssd;
165extern unsigned int speculative_prefetch_max;
166extern unsigned int speculative_prefetch_max_iosize;
167extern unsigned int preheat_pages_max;
168extern unsigned int preheat_pages_min;
169extern long numvnodes;
170
171extern uuid_string_t bootsessionuuid_string;
172
173extern unsigned int vm_max_delayed_work_limit;
174extern unsigned int vm_max_batch;
175
176extern unsigned int vm_page_free_min;
177extern unsigned int vm_page_free_target;
178extern unsigned int vm_page_free_reserved;
179extern unsigned int vm_page_speculative_percentage;
180extern 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
194extern boolean_t    mach_timer_coalescing_enabled;
195
196extern uint64_t timer_deadline_tracking_bin_1, timer_deadline_tracking_bin_2;
197
198STATIC void
199fill_user32_eproc(proc_t, struct user32_eproc *__restrict);
200STATIC void
201fill_user32_externproc(proc_t, struct user32_extern_proc *__restrict);
202STATIC void
203fill_user64_eproc(proc_t, struct user64_eproc *__restrict);
204STATIC void
205fill_user64_proc(proc_t, struct user64_kinfo_proc *__restrict);
206STATIC void
207fill_user64_externproc(proc_t, struct user64_extern_proc *__restrict);
208STATIC void
209fill_user32_proc(proc_t, struct user32_kinfo_proc *__restrict);
210
211extern int
212kdbg_control(int *name, u_int namelen, user_addr_t where, size_t * sizep);
213#if NFSCLIENT
214extern int
215netboot_root(void);
216#endif
217int
218pcsamples_ops(int *name, u_int namelen, user_addr_t where, size_t *sizep,
219              proc_t p);
220__private_extern__ kern_return_t
221reset_vmobjectcache(unsigned int val1, unsigned int val2);
222int
223sysctl_procargs(int *name, u_int namelen, user_addr_t where,
224				size_t *sizep, proc_t cur_proc);
225STATIC int
226sysctl_procargsx(int *name, u_int namelen, user_addr_t where, size_t *sizep,
227                 proc_t cur_proc, int argc_yes);
228int
229sysctl_struct(user_addr_t oldp, size_t *oldlenp, user_addr_t newp,
230              size_t newlen, void *sp, int len);
231
232STATIC int sysdoproc_filt_KERN_PROC_PID(proc_t p, void * arg);
233STATIC int sysdoproc_filt_KERN_PROC_PGRP(proc_t p, void * arg);
234STATIC int sysdoproc_filt_KERN_PROC_TTY(proc_t p, void * arg);
235STATIC int  sysdoproc_filt_KERN_PROC_UID(proc_t p, void * arg);
236STATIC int  sysdoproc_filt_KERN_PROC_RUID(proc_t p, void * arg);
237#if CONFIG_LCTX
238STATIC int  sysdoproc_filt_KERN_PROC_LCID(proc_t p, void * arg);
239#endif
240int sysdoproc_callback(proc_t p, void *arg);
241
242
243/* forward declarations for non-static STATIC */
244STATIC void fill_loadavg64(struct loadavg *la, struct user64_loadavg *la64);
245STATIC void fill_loadavg32(struct loadavg *la, struct user32_loadavg *la32);
246STATIC int sysctl_handle_kern_threadname(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
247STATIC int sysctl_sched_stats(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
248STATIC int sysctl_sched_stats_enable(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
249STATIC int sysctl_kdebug_ops SYSCTL_HANDLER_ARGS;
250STATIC int sysctl_dotranslate SYSCTL_HANDLER_ARGS;
251STATIC int sysctl_doaffinity SYSCTL_HANDLER_ARGS;
252#if COUNT_SYSCALLS
253STATIC int sysctl_docountsyscalls SYSCTL_HANDLER_ARGS;
254#endif	/* COUNT_SYSCALLS */
255STATIC int sysctl_doprocargs SYSCTL_HANDLER_ARGS;
256STATIC int sysctl_doprocargs2 SYSCTL_HANDLER_ARGS;
257STATIC int sysctl_prochandle SYSCTL_HANDLER_ARGS;
258#if DEBUG
259STATIC int sysctl_dodebug SYSCTL_HANDLER_ARGS;
260#endif
261STATIC int sysctl_aiomax(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
262STATIC int sysctl_aioprocmax(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
263STATIC int sysctl_aiothreads(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
264STATIC int sysctl_maxproc(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
265STATIC int sysctl_osversion(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
266STATIC int sysctl_sysctl_bootargs(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
267STATIC int sysctl_maxvnodes(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
268STATIC int sysctl_securelvl(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
269STATIC int sysctl_domainname(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
270STATIC int sysctl_hostname(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
271STATIC int sysctl_procname(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
272STATIC int sysctl_boottime(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
273STATIC int sysctl_symfile(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
274#if NFSCLIENT
275STATIC int sysctl_netboot(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
276#endif
277#ifdef CONFIG_IMGSRC_ACCESS
278STATIC int sysctl_imgsrcdev(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
279#endif
280STATIC int sysctl_usrstack(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
281STATIC int sysctl_usrstack64(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
282STATIC int sysctl_coredump(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
283STATIC int sysctl_suid_coredump(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
284STATIC int sysctl_delayterm(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
285STATIC int sysctl_rage_vnode(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
286STATIC int sysctl_kern_check_openevt(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
287STATIC int sysctl_nx(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
288STATIC int sysctl_loadavg(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
289STATIC int sysctl_vm_toggle_address_reuse(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
290STATIC int sysctl_swapusage(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
291#if defined(__i386__) || defined(__x86_64__)
292STATIC int sysctl_sysctl_exec_affinity(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
293#endif
294STATIC int fetch_process_cputype( proc_t cur_proc, int *name, u_int namelen, cpu_type_t *cputype);
295STATIC int sysctl_sysctl_native(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
296STATIC int sysctl_sysctl_cputype(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
297STATIC int sysctl_safeboot(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
298STATIC int sysctl_singleuser(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
299STATIC int sysctl_slide(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
300
301
302extern void IORegistrySetOSBuildVersion(char * build_version);
303
304STATIC void
305fill_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
313STATIC void
314fill_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 */
370int sysctl_mem_lock(user_addr_t old_addr, user_size_t old_len, user_addr_t new_addr, user_size_t new_len);
371int
372sysctl_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 */
382int
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 */
562extern char corefilename[MAXPATHLEN+1];
563extern int do_coredump;
564extern int sugid_coredump;
565
566#if COUNT_SYSCALLS
567extern int do_count_syscalls;
568#endif
569
570#ifdef INSECURE
571int securelevel = -1;
572#else
573int securelevel;
574#endif
575
576STATIC int
577sysctl_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}
612SYSCTL_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
619STATIC int
620sysctl_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 */
668SYSCTL_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
675STATIC int
676sysctl_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
732SYSCTL_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
735STATIC int
736sysctl_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	}
773out:
774	FREE(buf, M_TEMP);
775	return error;
776}
777
778SYSCTL_PROC(_kern, OID_AUTO, sched_stats, CTLFLAG_LOCKED, 0, 0, sysctl_sched_stats, "-", "");
779
780STATIC int
781sysctl_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
798SYSCTL_PROC(_kern, OID_AUTO, sched_stats_enable, CTLFLAG_LOCKED | CTLFLAG_WR, 0, 0, sysctl_sched_stats_enable, "-", "");
799
800extern int get_kernel_symfile(proc_t, char **);
801
802#if COUNT_SYSCALLS
803#define KERN_COUNT_SYSCALLS (KERN_OSTYPE + 1000)
804
805extern int 	nsysent;
806extern int syscalls_log[];
807extern const char *syscallnames[];
808
809STATIC int
810sysctl_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}
862SYSCTL_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
875extern
876#endif /* DIAGNOSTIC */
877struct ctldebug debug0, debug1;
878struct ctldebug debug2, debug3, debug4;
879struct ctldebug debug5, debug6, debug7, debug8, debug9;
880struct ctldebug debug10, debug11, debug12, debug13, debug14;
881struct ctldebug debug15, debug16, debug17, debug18, debug19;
882STATIC 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};
888STATIC int
889sysctl_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 */
932SYSCTL_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");
938SYSCTL_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 */
960int
961sysctl_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 */
985int
986sysctl_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 */
1006int
1007sysctl_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 */
1029int
1030sysctl_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 */
1056int
1057sysctl_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 */
1093int
1094sysctl_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 */
1121int
1122sysctl_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 */
1144int
1145sysctl_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 */
1169int
1170sysctl_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
1187STATIC int
1188sysdoproc_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
1196STATIC int
1197sysdoproc_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
1205STATIC int
1206sysdoproc_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
1228STATIC int
1229sysdoproc_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
1247STATIC int
1248sysdoproc_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
1266STATIC int
1267sysdoproc_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))
1281struct 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
1295int
1296sysdoproc_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
1325SYSCTL_NODE(_kern, KERN_PROC, proc, CTLFLAG_RD | CTLFLAG_LOCKED, 0, "");
1326STATIC int
1327sysctl_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 */
1453SYSCTL_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	"");
1459SYSCTL_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	"");
1465SYSCTL_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	"");
1471SYSCTL_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	"");
1477SYSCTL_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	"");
1483SYSCTL_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	"");
1489SYSCTL_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 */
1500STATIC void
1501fill_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 */
1560STATIC void
1561fill_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 */
1621STATIC void
1622fill_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 */
1671STATIC void
1672fill_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
1714STATIC void
1715fill_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
1722STATIC void
1723fill_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
1729STATIC int
1730sysctl_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}
1795SYSCTL_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 */
1807STATIC int
1808sysctl_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}
1827SYSCTL_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
1834STATIC int
1835sysctl_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}
1854SYSCTL_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
1861STATIC int
1862sysctl_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 */
2117STATIC int
2118sysctl_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 */
2137STATIC int
2138sysctl_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 */
2157STATIC int
2158sysctl_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 */
2179STATIC int
2180sysctl_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
2197SYSCTL_STRING(_kern, KERN_OSTYPE, ostype,
2198		CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED,
2199		ostype, 0, "");
2200SYSCTL_STRING(_kern, KERN_OSRELEASE, osrelease,
2201		CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED,
2202		osrelease, 0, "");
2203SYSCTL_INT(_kern, KERN_OSREV, osrevision,
2204		CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED,
2205		(int *)NULL, BSD, "");
2206SYSCTL_STRING(_kern, KERN_VERSION, version,
2207		CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED,
2208		version, 0, "");
2209SYSCTL_STRING(_kern, OID_AUTO, uuid,
2210		CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED,
2211		&kernel_uuid_string[0], 0, "");
2212
2213#if DEBUG
2214int debug_kprint_syscall = 0;
2215char debug_kprint_syscall_process[MAXCOMLEN+1];
2216
2217/* Thread safe: bits and string value are not used to reclaim state */
2218SYSCTL_INT (_debug, OID_AUTO, kprint_syscall,
2219	    CTLFLAG_RW | CTLFLAG_LOCKED, &debug_kprint_syscall, 0, "kprintf syscall tracing");
2220SYSCTL_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
2224int 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
2257STATIC int
2258sysctl_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
2271SYSCTL_PROC(_kern, KERN_OSVERSION, osversion,
2272        CTLFLAG_RW | CTLFLAG_KERN | CTLTYPE_STRING | CTLFLAG_LOCKED,
2273        osversion, 256 /* OSVERSIZE*/,
2274        sysctl_osversion, "A", "");
2275
2276STATIC int
2277sysctl_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
2288SYSCTL_PROC(_kern, OID_AUTO, bootargs,
2289	CTLFLAG_LOCKED | CTLFLAG_RD | CTLFLAG_KERN | CTLTYPE_STRING,
2290	NULL, 0,
2291	sysctl_sysctl_bootargs, "A", "bootargs");
2292
2293SYSCTL_INT(_kern, KERN_MAXFILES, maxfiles,
2294		CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED,
2295		&maxfiles, 0, "");
2296SYSCTL_INT(_kern, KERN_ARGMAX, argmax,
2297		CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED,
2298		(int *)NULL, ARG_MAX, "");
2299SYSCTL_INT(_kern, KERN_POSIX1, posix1version,
2300		CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED,
2301		(int *)NULL, _POSIX_VERSION, "");
2302SYSCTL_INT(_kern, KERN_NGROUPS, ngroups,
2303		CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED,
2304		(int *)NULL, NGROUPS_MAX, "");
2305SYSCTL_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> */
2309SYSCTL_INT(_kern, KERN_SAVED_IDS, saved_ids,
2310		CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED,
2311		(int *)NULL, 1, "");
2312#else
2313SYSCTL_INT(_kern, KERN_SAVED_IDS, saved_ids,
2314		CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED,
2315		NULL, 0, "");
2316#endif
2317SYSCTL_INT(_kern, OID_AUTO, num_files,
2318		CTLFLAG_RD | CTLFLAG_LOCKED,
2319		&nfiles, 0, "");
2320SYSCTL_COMPAT_INT(_kern, OID_AUTO, num_vnodes,
2321		CTLFLAG_RD | CTLFLAG_LOCKED,
2322		&numvnodes, 0, "");
2323SYSCTL_INT(_kern, OID_AUTO, num_tasks,
2324		CTLFLAG_RD | CTLFLAG_LOCKED,
2325		&task_max, 0, "");
2326SYSCTL_INT(_kern, OID_AUTO, num_threads,
2327		CTLFLAG_RD | CTLFLAG_LOCKED,
2328		&thread_max, 0, "");
2329SYSCTL_INT(_kern, OID_AUTO, num_taskthreads,
2330		CTLFLAG_RD | CTLFLAG_LOCKED,
2331		&task_threadmax, 0, "");
2332
2333STATIC int
2334sysctl_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
2347SYSCTL_INT(_kern, OID_AUTO, namecache_disabled,
2348		CTLFLAG_RW | CTLFLAG_LOCKED,
2349		&nc_disabled, 0, "");
2350
2351SYSCTL_PROC(_kern, KERN_MAXVNODES, maxvnodes,
2352		CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
2353		0, 0, sysctl_maxvnodes, "I", "");
2354
2355SYSCTL_PROC(_kern, KERN_MAXPROC, maxproc,
2356		CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
2357		0, 0, sysctl_maxproc, "I", "");
2358
2359SYSCTL_PROC(_kern, KERN_AIOMAX, aiomax,
2360		CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
2361		0, 0, sysctl_aiomax, "I", "");
2362
2363SYSCTL_PROC(_kern, KERN_AIOPROCMAX, aioprocmax,
2364		CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
2365		0, 0, sysctl_aioprocmax, "I", "");
2366
2367SYSCTL_PROC(_kern, KERN_AIOTHREADS, aiothreads,
2368		CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
2369		0, 0, sysctl_aiothreads, "I", "");
2370
2371STATIC int
2372sysctl_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
2389SYSCTL_PROC(_kern, KERN_SECURELVL, securelevel,
2390		CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
2391		0, 0, sysctl_securelvl, "I", "");
2392
2393
2394STATIC int
2395sysctl_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
2406SYSCTL_PROC(_kern, KERN_DOMAINNAME, nisdomainname,
2407		CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_LOCKED,
2408		0, 0, sysctl_domainname, "A", "");
2409
2410SYSCTL_COMPAT_INT(_kern, KERN_HOSTID, hostid,
2411		CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED,
2412		&hostid, 0, "");
2413
2414STATIC int
2415sysctl_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
2427SYSCTL_PROC(_kern, KERN_HOSTNAME, hostname,
2428		CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_LOCKED,
2429		0, 0, sysctl_hostname, "A", "");
2430
2431STATIC int
2432sysctl_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
2440SYSCTL_PROC(_kern, KERN_PROCNAME, procname,
2441		CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_ANYBODY | CTLFLAG_LOCKED,
2442		0, 0, sysctl_procname, "A", "");
2443
2444SYSCTL_INT(_kern, KERN_SPECULATIVE_READS, speculative_reads_disabled,
2445		CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED,
2446		&speculative_reads_disabled, 0, "");
2447
2448SYSCTL_INT(_kern, OID_AUTO, ignore_is_ssd,
2449		CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED,
2450		&ignore_is_ssd, 0, "");
2451
2452SYSCTL_UINT(_kern, OID_AUTO, preheat_pages_max,
2453		CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED,
2454		&preheat_pages_max, 0, "");
2455
2456SYSCTL_UINT(_kern, OID_AUTO, preheat_pages_min,
2457		CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED,
2458		&preheat_pages_min, 0, "");
2459
2460SYSCTL_UINT(_kern, OID_AUTO, speculative_prefetch_max,
2461		CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED,
2462		&speculative_prefetch_max, 0, "");
2463
2464SYSCTL_UINT(_kern, OID_AUTO, speculative_prefetch_max_iosize,
2465		CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED,
2466		&speculative_prefetch_max_iosize, 0, "");
2467
2468SYSCTL_UINT(_kern, OID_AUTO, vm_page_free_target,
2469		CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED,
2470		&vm_page_free_target, 0, "");
2471
2472SYSCTL_UINT(_kern, OID_AUTO, vm_page_free_min,
2473		CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED,
2474		&vm_page_free_min, 0, "");
2475
2476SYSCTL_UINT(_kern, OID_AUTO, vm_page_free_reserved,
2477		CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED,
2478		&vm_page_free_reserved, 0, "");
2479
2480SYSCTL_UINT(_kern, OID_AUTO, vm_page_speculative_percentage,
2481		CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED,
2482		&vm_page_speculative_percentage, 0, "");
2483
2484SYSCTL_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
2488SYSCTL_UINT(_kern, OID_AUTO, vm_max_delayed_work_limit,
2489		CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED,
2490		&vm_max_delayed_work_limit, 0, "");
2491
2492SYSCTL_UINT(_kern, OID_AUTO, vm_max_batch,
2493		CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED,
2494		&vm_max_batch, 0, "");
2495
2496SYSCTL_STRING(_kern, OID_AUTO, bootsessionuuid,
2497		CTLFLAG_RD | CTLFLAG_LOCKED,
2498		&bootsessionuuid_string, sizeof(bootsessionuuid_string) , "");
2499
2500STATIC int
2501sysctl_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
2520SYSCTL_PROC(_kern, KERN_BOOTTIME, boottime,
2521		CTLTYPE_STRUCT | CTLFLAG_RD | CTLFLAG_LOCKED,
2522		0, 0, sysctl_boottime, "S,timeval", "");
2523
2524STATIC int
2525sysctl_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
2536SYSCTL_PROC(_kern, KERN_SYMFILE, symfile,
2537		CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_LOCKED,
2538		0, 0, sysctl_symfile, "A", "");
2539
2540#if NFSCLIENT
2541STATIC int
2542sysctl_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
2548SYSCTL_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 */
2557STATIC int
2558sysctl_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);
2587out:
2588	vnode_put(imgsrc_rootvnodes[0]);
2589	return result;
2590}
2591
2592SYSCTL_PROC(_kern, OID_AUTO, imgsrcdev,
2593		CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
2594		0, 0, sysctl_imgsrcdev, "I", "");
2595
2596STATIC int
2597sysctl_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
2653SYSCTL_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
2660SYSCTL_DECL(_kern_timer);
2661SYSCTL_NODE(_kern, OID_AUTO, timer, CTLFLAG_RW | CTLFLAG_LOCKED, 0, "timer");
2662
2663SYSCTL_INT(_kern_timer, OID_AUTO, coalescing_enabled,
2664		CTLFLAG_KERN | CTLFLAG_RW | CTLFLAG_LOCKED,
2665		&mach_timer_coalescing_enabled, 0, "");
2666
2667SYSCTL_QUAD(_kern_timer, OID_AUTO, deadline_tracking_bin_1,
2668		CTLFLAG_RW | CTLFLAG_LOCKED,
2669		&timer_deadline_tracking_bin_1, "");
2670SYSCTL_QUAD(_kern_timer, OID_AUTO, deadline_tracking_bin_2,
2671		CTLFLAG_RW | CTLFLAG_LOCKED,
2672		&timer_deadline_tracking_bin_2, "");
2673
2674SYSCTL_DECL(_kern_timer_longterm);
2675SYSCTL_NODE(_kern_timer, OID_AUTO, longterm, CTLFLAG_RW | CTLFLAG_LOCKED, 0, "longterm");
2676
2677/* Must match definition in osfmk/kern/timer_call.c */
2678enum {
2679	THRESHOLD, QCOUNT,
2680	ENQUEUES, DEQUEUES, ESCALATES, SCANS, PREEMPTS,
2681	LATENCY, LATENCY_MIN, LATENCY_MAX
2682};
2683extern uint64_t	timer_sysctl_get(int);
2684extern int      timer_sysctl_set(int, uint64_t);
2685
2686STATIC int
2687sysctl_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
2703SYSCTL_PROC(_kern_timer_longterm, OID_AUTO, threshold,
2704		CTLTYPE_QUAD | CTLFLAG_RW | CTLFLAG_LOCKED,
2705		(void *) THRESHOLD, 0, sysctl_timer, "Q", "");
2706SYSCTL_PROC(_kern_timer_longterm, OID_AUTO, qlen,
2707		CTLTYPE_QUAD | CTLFLAG_RD | CTLFLAG_LOCKED,
2708		(void *) QCOUNT, 0, sysctl_timer, "Q", "");
2709#if DEBUG
2710SYSCTL_PROC(_kern_timer_longterm, OID_AUTO, enqueues,
2711		CTLTYPE_QUAD | CTLFLAG_RD | CTLFLAG_LOCKED,
2712		(void *) ENQUEUES, 0, sysctl_timer, "Q", "");
2713SYSCTL_PROC(_kern_timer_longterm, OID_AUTO, dequeues,
2714		CTLTYPE_QUAD | CTLFLAG_RD | CTLFLAG_LOCKED,
2715		(void *) DEQUEUES, 0, sysctl_timer, "Q", "");
2716SYSCTL_PROC(_kern_timer_longterm, OID_AUTO, escalates,
2717		CTLTYPE_QUAD | CTLFLAG_RD | CTLFLAG_LOCKED,
2718		(void *) ESCALATES, 0, sysctl_timer, "Q", "");
2719SYSCTL_PROC(_kern_timer_longterm, OID_AUTO, scans,
2720		CTLTYPE_QUAD | CTLFLAG_RD | CTLFLAG_LOCKED,
2721		(void *) SCANS, 0, sysctl_timer, "Q", "");
2722SYSCTL_PROC(_kern_timer_longterm, OID_AUTO, preempts,
2723		CTLTYPE_QUAD | CTLFLAG_RD | CTLFLAG_LOCKED,
2724		(void *) PREEMPTS, 0, sysctl_timer, "Q", "");
2725SYSCTL_PROC(_kern_timer_longterm, OID_AUTO, latency,
2726		CTLTYPE_QUAD | CTLFLAG_RD | CTLFLAG_LOCKED,
2727		(void *) LATENCY, 0, sysctl_timer, "Q", "");
2728SYSCTL_PROC(_kern_timer_longterm, OID_AUTO, latency_min,
2729		CTLTYPE_QUAD | CTLFLAG_RD | CTLFLAG_LOCKED,
2730		(void *) LATENCY_MIN, 0, sysctl_timer, "Q", "");
2731SYSCTL_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
2736STATIC int
2737sysctl_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
2743SYSCTL_PROC(_kern, KERN_USRSTACK32, usrstack,
2744		CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
2745		0, 0, sysctl_usrstack, "I", "");
2746
2747STATIC int
2748sysctl_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
2754SYSCTL_PROC(_kern, KERN_USRSTACK64, usrstack64,
2755		CTLTYPE_QUAD | CTLFLAG_RD | CTLFLAG_LOCKED,
2756		0, 0, sysctl_usrstack64, "Q", "");
2757
2758SYSCTL_STRING(_kern, KERN_COREFILE, corefile,
2759		CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED,
2760		corefilename, sizeof(corefilename), "");
2761
2762STATIC int
2763sysctl_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
2780SYSCTL_PROC(_kern, KERN_COREDUMP, coredump,
2781		CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
2782		0, 0, sysctl_coredump, "I", "");
2783
2784STATIC int
2785sysctl_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
2802SYSCTL_PROC(_kern, KERN_SUGID_COREDUMP, sugid_coredump,
2803		CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
2804		0, 0, sysctl_suid_coredump, "I", "");
2805
2806STATIC int
2807sysctl_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
2824SYSCTL_PROC(_kern, KERN_PROCDELAYTERM, delayterm,
2825		CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
2826		0, 0, sysctl_delayterm, "I", "");
2827
2828
2829STATIC int
2830sysctl_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
2874SYSCTL_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 */
2879STATIC int
2880sysctl_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
2911SYSCTL_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
2916STATIC int
2917sysctl_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
2949SYSCTL_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
2954STATIC int
2955sysctl_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
2983SYSCTL_PROC(_kern, KERN_NX_PROTECTION, nx,
2984		CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED,
2985		0, 0, sysctl_nx, "I", "");
2986
2987STATIC int
2988sysctl_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
3002SYSCTL_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 */
3009STATIC int
3010sysctl_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
3024SYSCTL_PROC(_debug, OID_AUTO, toggle_address_reuse, CTLFLAG_ANYBODY | CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED, 0, 0, sysctl_vm_toggle_address_reuse,"I","");
3025
3026STATIC int
3027sysctl_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
3054SYSCTL_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
3059extern void vm_page_reactivate_all_throttled(void);
3060
3061static int
3062sysctl_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
3092SYSCTL_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() */
3096SYSCTL_INT(_kern, KERN_SHREG_PRIVATIZABLE, shreg_private,
3097		CTLFLAG_RD | CTLFLAG_LOCKED,
3098		(int *)NULL, 0, "");
3099
3100#if defined(__i386__) || defined(__x86_64__)
3101STATIC int
3102sysctl_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}
3129SYSCTL_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
3132STATIC int
3133fetch_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);
3171out:
3172	return (error);
3173}
3174
3175STATIC int
3176sysctl_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}
3188SYSCTL_PROC(_sysctl, OID_AUTO, proc_native, CTLTYPE_NODE|CTLFLAG_RD | CTLFLAG_LOCKED, 0, 0, sysctl_sysctl_native ,"I","proc_native");
3189
3190STATIC int
3191sysctl_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}
3200SYSCTL_PROC(_sysctl, OID_AUTO, proc_cputype, CTLTYPE_NODE|CTLFLAG_RD | CTLFLAG_LOCKED, 0, 0, sysctl_sysctl_cputype ,"I","proc_cputype");
3201
3202STATIC int
3203sysctl_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
3209SYSCTL_PROC(_kern, KERN_SAFEBOOT, safeboot,
3210		CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
3211		0, 0, sysctl_safeboot, "I", "");
3212
3213STATIC int
3214sysctl_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
3220SYSCTL_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 */
3227extern boolean_t	affinity_sets_enabled;
3228extern int		affinity_sets_mapping;
3229
3230SYSCTL_INT (_kern, OID_AUTO, affinity_sets_enabled,
3231	    CTLFLAG_RW | CTLFLAG_LOCKED, (int *) &affinity_sets_enabled, 0, "hinting enabled");
3232SYSCTL_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 */
3238STATIC int
3239sysctl_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
3249SYSCTL_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
3266vm_map_size_t	vm_global_no_user_wire_amount;
3267vm_map_size_t	vm_global_user_wire_limit;
3268vm_map_size_t	vm_user_wire_limit;
3269
3270/*
3271 * There needs to be a more automatic/elegant way to do this
3272 */
3273SYSCTL_QUAD(_vm, OID_AUTO, global_no_user_wire_amount, CTLFLAG_RW | CTLFLAG_LOCKED, &vm_global_no_user_wire_amount, "");
3274SYSCTL_QUAD(_vm, OID_AUTO, global_user_wire_limit, CTLFLAG_RW | CTLFLAG_LOCKED, &vm_global_user_wire_limit, "");
3275SYSCTL_QUAD(_vm, OID_AUTO, user_wire_limit, CTLFLAG_RW | CTLFLAG_LOCKED, &vm_user_wire_limit, "");
3276
3277extern int vm_map_copy_overwrite_aligned_src_not_internal;
3278extern int vm_map_copy_overwrite_aligned_src_not_symmetric;
3279extern int vm_map_copy_overwrite_aligned_src_large;
3280SYSCTL_INT(_vm, OID_AUTO, vm_copy_src_not_internal, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_map_copy_overwrite_aligned_src_not_internal, 0, "");
3281SYSCTL_INT(_vm, OID_AUTO, vm_copy_src_not_symmetric, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_map_copy_overwrite_aligned_src_not_symmetric, 0, "");
3282SYSCTL_INT(_vm, OID_AUTO, vm_copy_src_large, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_map_copy_overwrite_aligned_src_large, 0, "");
3283
3284
3285extern uint32_t	vm_page_external_count;
3286extern uint32_t	vm_page_filecache_min;
3287
3288SYSCTL_INT(_vm, OID_AUTO, vm_page_external_count, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_page_external_count, 0, "");
3289SYSCTL_INT(_vm, OID_AUTO, vm_page_filecache_min, CTLFLAG_RW | CTLFLAG_LOCKED, &vm_page_filecache_min, 0, "");
3290
3291extern int	vm_compressor_mode;
3292extern uint32_t	swapout_target_age;
3293extern int64_t  compressor_bytes_used;
3294extern uint32_t	compressor_eval_period_in_msecs;
3295extern uint32_t	compressor_sample_min_in_msecs;
3296extern uint32_t	compressor_sample_max_in_msecs;
3297extern uint32_t	compressor_thrashing_threshold_per_10msecs;
3298extern uint32_t	compressor_thrashing_min_per_10msecs;
3299extern uint32_t	vm_compressor_minorcompact_threshold_divisor;
3300extern uint32_t	vm_compressor_majorcompact_threshold_divisor;
3301extern uint32_t	vm_compressor_unthrottle_threshold_divisor;
3302extern uint32_t	vm_compressor_catchup_threshold_divisor;
3303
3304SYSCTL_INT(_vm, OID_AUTO, compressor_mode, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_compressor_mode, 0, "");
3305SYSCTL_QUAD(_vm, OID_AUTO, compressor_bytes_used, CTLFLAG_RD | CTLFLAG_LOCKED, &compressor_bytes_used, "");
3306SYSCTL_INT(_vm, OID_AUTO, compressor_swapout_target_age, CTLFLAG_RD | CTLFLAG_LOCKED, &swapout_target_age, 0, "");
3307
3308SYSCTL_INT(_vm, OID_AUTO, compressor_eval_period_in_msecs, CTLFLAG_RW | CTLFLAG_LOCKED, &compressor_eval_period_in_msecs, 0, "");
3309SYSCTL_INT(_vm, OID_AUTO, compressor_sample_min_in_msecs, CTLFLAG_RW | CTLFLAG_LOCKED, &compressor_sample_min_in_msecs, 0, "");
3310SYSCTL_INT(_vm, OID_AUTO, compressor_sample_max_in_msecs, CTLFLAG_RW | CTLFLAG_LOCKED, &compressor_sample_max_in_msecs, 0, "");
3311SYSCTL_INT(_vm, OID_AUTO, compressor_thrashing_threshold_per_10msecs, CTLFLAG_RW | CTLFLAG_LOCKED, &compressor_thrashing_threshold_per_10msecs, 0, "");
3312SYSCTL_INT(_vm, OID_AUTO, compressor_thrashing_min_per_10msecs, CTLFLAG_RW | CTLFLAG_LOCKED, &compressor_thrashing_min_per_10msecs, 0, "");
3313SYSCTL_INT(_vm, OID_AUTO, compressor_minorcompact_threshold_divisor, CTLFLAG_RW | CTLFLAG_LOCKED, &vm_compressor_minorcompact_threshold_divisor, 0, "");
3314SYSCTL_INT(_vm, OID_AUTO, compressor_majorcompact_threshold_divisor, CTLFLAG_RW | CTLFLAG_LOCKED, &vm_compressor_majorcompact_threshold_divisor, 0, "");
3315SYSCTL_INT(_vm, OID_AUTO, compressor_unthrottle_threshold_divisor, CTLFLAG_RW | CTLFLAG_LOCKED, &vm_compressor_unthrottle_threshold_divisor, 0, "");
3316SYSCTL_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
3322extern	uint32_t        kdebug_thread_block;
3323
3324SYSCTL_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 */
3330SYSCTL_INT (_kern, OID_AUTO, stack_size,
3331	    CTLFLAG_RD | CTLFLAG_LOCKED, (int *) &kernel_stack_size, 0, "Kernel stack size");
3332SYSCTL_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 */
3338extern int ipc_portbt;
3339
3340SYSCTL_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
3354extern char sched_string[SCHED_STRING_MAX_LENGTH];
3355SYSCTL_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 */
3364