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