2 * Copyright (c) 2006 Apple Computer, Inc. All Rights Reserved.
4 * @APPLE_LICENSE_OSREFERENCE_HEADER_START@
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
10 * License may not be used to create, or enable the creation or
11 * redistribution of, unlawful or unlicensed copies of an Apple operating
12 * system, or to circumvent, violate, or enable the circumvention or
13 * violation of, any terms of an Apple operating system software license
16 * Please obtain a copy of the License at
17 * http://www.opensource.apple.com/apsl/ and read it before using this
20 * The Original Code and all software distributed under the License are
21 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
22 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
23 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
25 * Please see the License for the specific language governing rights and
26 * limitations under the License.
28 * @APPLE_LICENSE_OSREFERENCE_HEADER_END@
30 /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
32 * Copyright (c) 1982, 1986, 1989, 1993
33 * The Regents of the University of California. All rights reserved.
35 * This code is derived from software contributed to Berkeley by
36 * Mike Karels at Berkeley Software Design, Inc.
38 * Redistribution and use in source and binary forms, with or without
39 * modification, are permitted provided that the following conditions
41 * 1. Redistributions of source code must retain the above copyright
42 * notice, this list of conditions and the following disclaimer.
43 * 2. Redistributions in binary form must reproduce the above copyright
44 * notice, this list of conditions and the following disclaimer in the
45 * documentation and/or other materials provided with the distribution.
46 * 3. All advertising materials mentioning features or use of this software
47 * must display the following acknowledgement:
48 * This product includes software developed by the University of
49 * California, Berkeley and its contributors.
50 * 4. Neither the name of the University nor the names of its contributors
51 * may be used to endorse or promote products derived from this software
52 * without specific prior written permission.
54 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
55 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
56 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
57 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
58 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
59 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
60 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
61 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
62 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
63 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
66 * @(#)kern_sysctl.c 8.4 (Berkeley) 4/14/94
73 #include <sys/param.h>
74 #include <sys/systm.h>
75 #include <sys/kernel.h>
76 #include <sys/malloc.h>
77 #include <sys/proc_internal.h>
78 #include <sys/kauth.h>
79 #include <sys/file_internal.h>
80 #include <sys/vnode_internal.h>
81 #include <sys/unistd.h>
83 #include <sys/ioctl.h>
84 #include <sys/namei.h>
86 #include <sys/disklabel.h>
88 #include <sys/sysctl.h>
90 #include <sys/aio_kern.h>
92 #include <bsm/audit_kernel.h>
94 #include <mach/machine.h>
95 #include <mach/mach_types.h>
96 #include <mach/vm_param.h>
97 #include <kern/task.h>
98 #include <kern/lock.h>
99 #include <vm/vm_kern.h>
100 #include <vm/vm_map.h>
101 #include <mach/host_info.h>
103 extern vm_map_t bsd_pageable_map
;
105 #include <sys/mount_internal.h>
106 #include <sys/kdebug.h>
107 #include <sys/sysproto.h>
109 #include <IOKit/IOPlatformExpert.h>
110 #include <pexpert/pexpert.h>
112 #include <machine/machine_routines.h>
114 #include <vm/vm_protos.h>
116 sysctlfn kern_sysctl
;
118 sysctlfn debug_sysctl
;
120 extern sysctlfn vm_sysctl
;
121 extern sysctlfn vfs_sysctl
;
122 extern sysctlfn net_sysctl
;
123 extern sysctlfn cpu_sysctl
;
124 extern int aio_max_requests
;
125 extern int aio_max_requests_per_process
;
126 extern int aio_worker_threads
;
127 extern int maxprocperuid
;
128 extern int maxfilesperproc
;
129 extern int lowpri_IO_window_msecs
;
130 extern int lowpri_IO_delay_msecs
;
133 fill_eproc(struct proc
*p
, struct eproc
*ep
);
135 fill_externproc(struct proc
*p
, struct extern_proc
*exp
);
137 fill_user_eproc(struct proc
*p
, struct user_eproc
*ep
);
139 fill_user_proc(struct proc
*p
, struct user_kinfo_proc
*kp
);
141 fill_user_externproc(struct proc
*p
, struct user_extern_proc
*exp
);
143 kdbg_control(int *name
, u_int namelen
, user_addr_t where
, size_t * sizep
);
145 kdebug_ops(int *name
, u_int namelen
, user_addr_t where
, size_t *sizep
, struct proc
*p
);
151 pcsamples_ops(int *name
, u_int namelen
, user_addr_t where
, size_t *sizep
,
153 __private_extern__ kern_return_t
154 reset_vmobjectcache(unsigned int val1
, unsigned int val2
);
156 resize_namecache(u_int newsize
);
158 sysctl_aiomax(user_addr_t oldp
, size_t *oldlenp
, user_addr_t newp
, size_t newlen
);
160 sysctl_aioprocmax(user_addr_t oldp
, size_t *oldlenp
, user_addr_t newp
, size_t newlen
);
162 sysctl_aiothreads(user_addr_t oldp
, size_t *oldlenp
, user_addr_t newp
, size_t newlen
);
164 sysctl_clockrate(user_addr_t where
, size_t *sizep
);
166 sysctl_doproc(int *name
, u_int namelen
, user_addr_t where
, size_t *sizep
);
168 sysctl_doprof(int *name
, u_int namelen
, user_addr_t oldp
, size_t *oldlenp
,
169 user_addr_t newp
, size_t newlen
);
171 sysctl_file(user_addr_t where
, size_t *sizep
);
173 fill_proc(struct proc
*p
, struct kinfo_proc
*kp
);
175 sysctl_maxfilesperproc(user_addr_t oldp
, size_t *oldlenp
,
176 user_addr_t newp
, size_t newlen
);
178 sysctl_maxprocperuid(user_addr_t oldp
, size_t *oldlenp
,
179 user_addr_t newp
, size_t newlen
);
181 sysctl_maxproc(user_addr_t oldp
, size_t *oldlenp
,
182 user_addr_t newp
, size_t newlen
);
184 sysctl_procargs(int *name
, u_int namelen
, user_addr_t where
,
185 size_t *sizep
, struct proc
*cur_proc
);
187 sysctl_procargs2(int *name
, u_int namelen
, user_addr_t where
, size_t *sizep
,
188 struct proc
*cur_proc
);
190 sysctl_procargsx(int *name
, u_int namelen
, user_addr_t where
, size_t *sizep
,
191 struct proc
*cur_proc
, int argc_yes
);
193 sysctl_struct(user_addr_t oldp
, size_t *oldlenp
, user_addr_t newp
,
194 size_t newlen
, void *sp
, int len
);
196 sysctl_vnode(user_addr_t where
, size_t *sizep
);
200 * temporary location for vm_sysctl. This should be machine independant
203 extern uint32_t mach_factor
[3];
206 loadavg32to64(struct loadavg
*la32
, struct user_loadavg
*la64
)
208 la64
->ldavg
[0] = la32
->ldavg
[0];
209 la64
->ldavg
[1] = la32
->ldavg
[1];
210 la64
->ldavg
[2] = la32
->ldavg
[2];
211 la64
->fscale
= (user_long_t
)la32
->fscale
;
215 vm_sysctl(int *name
, __unused u_int namelen
, user_addr_t oldp
, size_t *oldlenp
,
216 user_addr_t newp
, size_t newlen
, __unused
struct proc
*p
)
218 struct loadavg loadinfo
;
222 if (proc_is64bit(p
)) {
223 struct user_loadavg loadinfo64
;
224 loadavg32to64(&averunnable
, &loadinfo64
);
225 return (sysctl_struct(oldp
, oldlenp
, newp
, newlen
,
226 &loadinfo64
, sizeof(loadinfo64
)));
228 return (sysctl_struct(oldp
, oldlenp
, newp
, newlen
,
229 &averunnable
, sizeof(struct loadavg
)));
232 loadinfo
.ldavg
[0] = mach_factor
[0];
233 loadinfo
.ldavg
[1] = mach_factor
[1];
234 loadinfo
.ldavg
[2] = mach_factor
[2];
235 loadinfo
.fscale
= LSCALE
;
236 if (proc_is64bit(p
)) {
237 struct user_loadavg loadinfo64
;
238 loadavg32to64(&loadinfo
, &loadinfo64
);
239 return (sysctl_struct(oldp
, oldlenp
, newp
, newlen
,
240 &loadinfo64
, sizeof(loadinfo64
)));
242 return (sysctl_struct(oldp
, oldlenp
, newp
, newlen
,
243 &loadinfo
, sizeof(struct loadavg
)));
249 uint32_t swap_pagesize
;
250 boolean_t swap_encrypted
;
251 struct xsw_usage xsu
;
253 error
= macx_swapinfo(&swap_total
,
260 xsu
.xsu_total
= swap_total
;
261 xsu
.xsu_avail
= swap_avail
;
262 xsu
.xsu_used
= swap_total
- swap_avail
;
263 xsu
.xsu_pagesize
= swap_pagesize
;
264 xsu
.xsu_encrypted
= swap_encrypted
;
265 return sysctl_struct(oldp
, oldlenp
, newp
, newlen
,
266 &xsu
, sizeof (struct xsw_usage
));
282 static struct sysctl_lock
{
289 __sysctl(struct proc
*p
, struct __sysctl_args
*uap
, __unused register_t
*retval
)
291 int error
, dolock
= 1;
292 size_t savelen
= 0, oldlen
= 0, newlen
;
293 sysctlfn
*fnp
= NULL
;
294 int name
[CTL_MAXNAME
];
299 * all top-level sysctl names are non-terminal
301 if (uap
->namelen
> CTL_MAXNAME
|| uap
->namelen
< 2)
303 error
= copyin(uap
->name
, &name
[0], uap
->namelen
* sizeof(int));
307 AUDIT_ARG(ctlname
, name
, uap
->namelen
);
309 if (proc_is64bit(p
)) {
310 /* uap->newlen is a size_t value which grows to 64 bits
311 * when coming from a 64-bit process. since it's doubtful we'll
312 * have a sysctl newp buffer greater than 4GB we shrink it to size_t
314 newlen
= CAST_DOWN(size_t, uap
->newlen
);
317 newlen
= uap
->newlen
;
320 /* CTL_UNSPEC is used to get oid to AUTO_OID */
321 if (uap
->new != USER_ADDR_NULL
322 && ((name
[0] == CTL_KERN
323 && !(name
[1] == KERN_IPC
|| name
[1] == KERN_PANICINFO
|| name
[1] == KERN_PROCDELAYTERM
||
324 name
[1] == KERN_PROC_LOW_PRI_IO
))
325 || (name
[0] == CTL_HW
)
326 || (name
[0] == CTL_VM
)
327 || (name
[0] == CTL_VFS
))
328 && (error
= suser(kauth_cred_get(), &p
->p_acflag
)))
334 if ((name
[1] != KERN_VNODE
) && (name
[1] != KERN_FILE
)
335 && (name
[1] != KERN_PROC
))
354 if (uap
->oldlenp
!= USER_ADDR_NULL
) {
355 uint64_t oldlen64
= fuulong(uap
->oldlenp
);
357 oldlen
= CAST_DOWN(size_t, oldlen64
);
359 * If more than 4G, clamp to 4G - useracc() below will catch
360 * with an EFAULT, if it's actually necessary.
362 if (oldlen64
> 0x00000000ffffffffULL
)
363 oldlen
= 0xffffffffUL
;
366 if (uap
->old
!= USER_ADDR_NULL
) {
367 if (!useracc(uap
->old
, (user_size_t
)oldlen
, B_WRITE
))
370 /* The pc sampling mechanism does not need to take this lock */
371 if ((name
[1] != KERN_PCSAMPLES
) &&
372 (!((name
[1] == KERN_KDEBUG
) && (name
[2] == KERN_KDGETENTROPY
)))) {
373 while (memlock
.sl_lock
) {
375 sleep((caddr_t
)&memlock
, PRIBIO
+1);
381 if (dolock
&& oldlen
&&
382 (error
= vslock(uap
->old
, (user_size_t
)oldlen
))) {
383 if ((name
[1] != KERN_PCSAMPLES
) &&
384 (! ((name
[1] == KERN_KDEBUG
) && (name
[2] == KERN_KDGETENTROPY
)))) {
386 if (memlock
.sl_want
) {
388 wakeup((caddr_t
)&memlock
);
397 error
= (*fnp
)(name
+ 1, uap
->namelen
- 1, uap
->old
,
398 &oldlen
, uap
->new, newlen
, p
);
403 if ( (name
[0] != CTL_VFS
) && (error
== ENOTSUP
)) {
405 error
= userland_sysctl(p
, name
, uap
->namelen
, uap
->old
, &tmp
,
406 1, uap
->new, newlen
, &oldlen
);
409 if (uap
->old
!= USER_ADDR_NULL
) {
410 if (dolock
&& savelen
) {
411 error1
= vsunlock(uap
->old
, (user_size_t
)savelen
, B_WRITE
);
412 if (!error
&& error1
)
415 if (name
[1] != KERN_PCSAMPLES
) {
417 if (memlock
.sl_want
) {
419 wakeup((caddr_t
)&memlock
);
423 if ((error
) && (error
!= ENOMEM
))
426 if (uap
->oldlenp
!= USER_ADDR_NULL
) {
427 i
= suulong(uap
->oldlenp
, oldlen
);
436 * Attributes stored in the kernel.
438 extern char classichandler
[32];
439 extern uint32_t classichandler_fsid
;
440 extern long classichandler_fileid
;
441 __private_extern__
char corefilename
[MAXPATHLEN
+1];
442 __private_extern__
int do_coredump
;
443 __private_extern__
int sugid_coredump
;
447 int securelevel
= -1;
459 __unused
size_t newSize
,
460 struct proc
*cur_proc
)
465 if (name
[0] == 0 && 1 == namelen
) {
466 return sysctl_rdint(oldBuf
, oldSize
, newBuf
,
467 (cur_proc
->p_flag
& P_AFFINITY
) ? 1 : 0);
468 } else if (name
[0] == 1 && 2 == namelen
) {
470 cur_proc
->p_flag
&= ~P_AFFINITY
;
472 cur_proc
->p_flag
|= P_AFFINITY
;
486 __unused
size_t newSize
,
487 struct proc
*cur_proc
)
498 if ((kauth_cred_getuid(p
->p_ucred
) != kauth_cred_getuid(kauth_cred_get()))
499 && suser(kauth_cred_get(), &cur_proc
->p_acflag
))
502 return sysctl_rdint(oldBuf
, oldSize
, newBuf
,
503 (p
->p_flag
& P_CLASSIC
) ? 1 : 0);
507 sysctl_classichandler(
509 __unused u_int namelen
,
519 struct vnode_attr va
;
520 char handler
[sizeof(classichandler
)];
521 struct vfs_context context
;
524 context
.vc_ucred
= kauth_cred_get();
527 len
= strlen(classichandler
) + 1;
531 error
= copyout(classichandler
, oldBuf
, len
);
538 error
= suser(context
.vc_ucred
, &p
->p_acflag
);
541 if (newSize
>= sizeof(classichandler
))
542 return (ENAMETOOLONG
);
543 error
= copyin(newBuf
, handler
, newSize
);
546 handler
[newSize
] = 0;
548 NDINIT(&nd
, LOOKUP
, FOLLOW
| LOCKLEAF
, UIO_SYSSPACE32
,
549 CAST_USER_ADDR_T(handler
), &context
);
555 /* Check mount point */
556 if ((nd
.ni_vp
->v_mount
->mnt_flag
& MNT_NOEXEC
) ||
557 (nd
.ni_vp
->v_type
!= VREG
)) {
563 VATTR_WANTED(&va
, va_fsid
);
564 VATTR_WANTED(&va
, va_fileid
);
565 error
= vnode_getattr(nd
.ni_vp
, &va
, &context
);
572 classichandler_fsid
= va
.va_fsid
;
573 classichandler_fileid
= (u_long
)va
.va_fileid
;
574 strcpy(classichandler
, handler
);
580 extern int get_kernel_symfile( struct proc
*, char **);
581 __private_extern__
int
582 sysctl_dopanicinfo(int *, u_int
, user_addr_t
, size_t *, user_addr_t
,
583 size_t, struct proc
*);
586 * kernel related system variables.
589 kern_sysctl(int *name
, u_int namelen
, user_addr_t oldp
, size_t *oldlenp
,
590 user_addr_t newp
, size_t newlen
, struct proc
*p
)
592 int error
, level
, inthostid
, tmp
;
593 unsigned int oldval
=0;
595 /* all sysctl names not listed below are terminal at this level */
597 && !(name
[0] == KERN_PROC
598 || name
[0] == KERN_PROF
599 || name
[0] == KERN_KDEBUG
600 || name
[0] == KERN_PROCARGS
601 || name
[0] == KERN_PROCARGS2
602 || name
[0] == KERN_PCSAMPLES
603 || name
[0] == KERN_IPC
604 || name
[0] == KERN_SYSV
605 || name
[0] == KERN_AFFINITY
606 || name
[0] == KERN_CLASSIC
607 || name
[0] == KERN_PANICINFO
608 || name
[0] == KERN_POSIX
)
610 return (ENOTDIR
); /* overloaded */
614 return (sysctl_rdstring(oldp
, oldlenp
, newp
, ostype
));
616 return (sysctl_rdstring(oldp
, oldlenp
, newp
, osrelease
));
618 return (sysctl_rdint(oldp
, oldlenp
, newp
, BSD
));
620 return (sysctl_rdstring(oldp
, oldlenp
, newp
, version
));
622 oldval
= desiredvnodes
;
623 error
= sysctl_int(oldp
, oldlenp
, newp
,
624 newlen
, &desiredvnodes
);
625 reset_vmobjectcache(oldval
, desiredvnodes
);
626 resize_namecache(desiredvnodes
);
629 return (sysctl_maxproc(oldp
, oldlenp
, newp
, newlen
));
631 return (sysctl_int(oldp
, oldlenp
, newp
, newlen
, &maxfiles
));
632 case KERN_MAXPROCPERUID
:
633 return( sysctl_maxprocperuid( oldp
, oldlenp
, newp
, newlen
) );
634 case KERN_MAXFILESPERPROC
:
635 return( sysctl_maxfilesperproc( oldp
, oldlenp
, newp
, newlen
) );
637 return (sysctl_rdint(oldp
, oldlenp
, newp
, ARG_MAX
));
640 if ((error
= sysctl_int(oldp
, oldlenp
, newp
, newlen
, &level
)) ||
641 newp
== USER_ADDR_NULL
)
643 if (level
< securelevel
&& p
->p_pid
!= 1)
648 error
= sysctl_trstring(oldp
, oldlenp
, newp
, newlen
,
649 hostname
, sizeof(hostname
));
651 hostnamelen
= newlen
;
653 case KERN_DOMAINNAME
:
654 error
= sysctl_string(oldp
, oldlenp
, newp
, newlen
,
655 domainname
, sizeof(domainname
));
657 domainnamelen
= newlen
;
660 inthostid
= hostid
; /* XXX assumes sizeof long <= sizeof int */
661 error
= sysctl_int(oldp
, oldlenp
, newp
, newlen
, &inthostid
);
665 return (sysctl_clockrate(oldp
, oldlenp
));
670 t
.tv_sec
= boottime_sec();
673 return (sysctl_rdstruct(oldp
, oldlenp
, newp
, &t
,
674 sizeof(struct timeval
)));
677 return (sysctl_vnode(oldp
, oldlenp
));
679 return (sysctl_doproc(name
+ 1, namelen
- 1, oldp
, oldlenp
));
681 return (sysctl_file(oldp
, oldlenp
));
684 return (sysctl_doprof(name
+ 1, namelen
- 1, oldp
, oldlenp
,
688 return (sysctl_rdint(oldp
, oldlenp
, newp
, _POSIX_VERSION
));
690 return (sysctl_rdint(oldp
, oldlenp
, newp
, NGROUPS_MAX
));
691 case KERN_JOB_CONTROL
:
692 return (sysctl_rdint(oldp
, oldlenp
, newp
, 1));
694 #ifdef _POSIX_SAVED_IDS
695 return (sysctl_rdint(oldp
, oldlenp
, newp
, 1));
697 return (sysctl_rdint(oldp
, oldlenp
, newp
, 0));
700 return (kdebug_ops(name
+ 1, namelen
- 1, oldp
, oldlenp
, p
));
702 return (pcsamples_ops(name
+ 1, namelen
- 1, oldp
, oldlenp
, p
));
704 /* new one as it does not use kinfo_proc */
705 return (sysctl_procargs(name
+ 1, namelen
- 1, oldp
, oldlenp
, p
));
707 /* new one as it does not use kinfo_proc */
708 return (sysctl_procargs2(name
+ 1, namelen
- 1, oldp
, oldlenp
, p
));
710 error
= get_kernel_symfile( p
, &str
);
713 return (sysctl_rdstring(oldp
, oldlenp
, newp
, str
));
716 return (sysctl_rdint(oldp
, oldlenp
, newp
, netboot_root()));
719 return(sysctl_dopanicinfo(name
+ 1, namelen
- 1, oldp
, oldlenp
,
722 return sysctl_affinity(name
+1, namelen
-1, oldp
, oldlenp
,
725 return sysctl_classic(name
+1, namelen
-1, oldp
, oldlenp
,
727 case KERN_CLASSICHANDLER
:
728 return sysctl_classichandler(name
+1, namelen
-1, oldp
, oldlenp
,
731 return( sysctl_aiomax( oldp
, oldlenp
, newp
, newlen
) );
732 case KERN_AIOPROCMAX
:
733 return( sysctl_aioprocmax( oldp
, oldlenp
, newp
, newlen
) );
734 case KERN_AIOTHREADS
:
735 return( sysctl_aiothreads( oldp
, oldlenp
, newp
, newlen
) );
737 return (sysctl_rdint(oldp
, oldlenp
, newp
, (uintptr_t)p
->user_stack
));
738 case KERN_USRSTACK64
:
739 return (sysctl_rdquad(oldp
, oldlenp
, newp
, p
->user_stack
));
741 error
= sysctl_string(oldp
, oldlenp
, newp
, newlen
,
742 corefilename
, sizeof(corefilename
));
746 error
= sysctl_int(oldp
, oldlenp
, newp
, newlen
, &do_coredump
);
747 if (!error
&& ((do_coredump
< 0) || (do_coredump
> 1))) {
752 case KERN_SUGID_COREDUMP
:
753 tmp
= sugid_coredump
;
754 error
= sysctl_int(oldp
, oldlenp
, newp
, newlen
, &sugid_coredump
);
755 if (!error
&& ((sugid_coredump
< 0) || (sugid_coredump
> 1))) {
756 sugid_coredump
= tmp
;
760 case KERN_PROCDELAYTERM
:
762 int old_value
, new_value
;
765 if (oldp
&& *oldlenp
< sizeof(int))
767 if ( newp
&& newlen
!= sizeof(int) )
769 *oldlenp
= sizeof(int);
770 old_value
= (p
->p_lflag
& P_LDELAYTERM
)? 1: 0;
771 if (oldp
&& (error
= copyout( &old_value
, oldp
, sizeof(int))))
773 if (error
== 0 && newp
)
774 error
= copyin( newp
, &new_value
, sizeof(int) );
775 if (error
== 0 && newp
) {
777 p
->p_lflag
|= P_LDELAYTERM
;
779 p
->p_lflag
&= ~P_LDELAYTERM
;
783 case KERN_PROC_LOW_PRI_IO
:
785 int old_value
, new_value
;
788 if (oldp
&& *oldlenp
< sizeof(int))
790 if ( newp
&& newlen
!= sizeof(int) )
792 *oldlenp
= sizeof(int);
794 old_value
= (p
->p_lflag
& P_LLOW_PRI_IO
)? 0x01: 0;
795 if (p
->p_lflag
& P_LBACKGROUND_IO
)
798 if (oldp
&& (error
= copyout( &old_value
, oldp
, sizeof(int))))
800 if (error
== 0 && newp
)
801 error
= copyin( newp
, &new_value
, sizeof(int) );
802 if (error
== 0 && newp
) {
803 if (new_value
& 0x01)
804 p
->p_lflag
|= P_LLOW_PRI_IO
;
805 else if (new_value
& 0x02)
806 p
->p_lflag
|= P_LBACKGROUND_IO
;
807 else if (new_value
== 0)
808 p
->p_lflag
&= ~(P_LLOW_PRI_IO
| P_LBACKGROUND_IO
);
812 case KERN_LOW_PRI_WINDOW
:
814 int old_value
, new_value
;
817 if (oldp
&& *oldlenp
< sizeof(old_value
) )
819 if ( newp
&& newlen
!= sizeof(new_value
) )
821 *oldlenp
= sizeof(old_value
);
823 old_value
= lowpri_IO_window_msecs
;
825 if (oldp
&& (error
= copyout( &old_value
, oldp
, *oldlenp
)))
827 if (error
== 0 && newp
)
828 error
= copyin( newp
, &new_value
, sizeof(newlen
) );
829 if (error
== 0 && newp
) {
830 lowpri_IO_window_msecs
= new_value
;
834 case KERN_LOW_PRI_DELAY
:
836 int old_value
, new_value
;
839 if (oldp
&& *oldlenp
< sizeof(old_value
) )
841 if ( newp
&& newlen
!= sizeof(new_value
) )
843 *oldlenp
= sizeof(old_value
);
845 old_value
= lowpri_IO_delay_msecs
;
847 if (oldp
&& (error
= copyout( &old_value
, oldp
, *oldlenp
)))
849 if (error
== 0 && newp
)
850 error
= copyin( newp
, &new_value
, sizeof(newlen
) );
851 if (error
== 0 && newp
) {
852 lowpri_IO_delay_msecs
= new_value
;
856 case KERN_SHREG_PRIVATIZABLE
:
857 /* this kernel does implement shared_region_make_private_np() */
858 return (sysctl_rdint(oldp
, oldlenp
, newp
, 1));
867 * Debugging related system variables.
871 #endif /* DIAGNOSTIC */
872 struct ctldebug debug0
, debug1
;
873 struct ctldebug debug2
, debug3
, debug4
;
874 struct ctldebug debug5
, debug6
, debug7
, debug8
, debug9
;
875 struct ctldebug debug10
, debug11
, debug12
, debug13
, debug14
;
876 struct ctldebug debug15
, debug16
, debug17
, debug18
, debug19
;
877 static struct ctldebug
*debugvars
[CTL_DEBUG_MAXID
] = {
878 &debug0
, &debug1
, &debug2
, &debug3
, &debug4
,
879 &debug5
, &debug6
, &debug7
, &debug8
, &debug9
,
880 &debug10
, &debug11
, &debug12
, &debug13
, &debug14
,
881 &debug15
, &debug16
, &debug17
, &debug18
, &debug19
,
884 debug_sysctl(int *name
, u_int namelen
, user_addr_t oldp
, size_t *oldlenp
,
885 user_addr_t newp
, size_t newlen
, struct proc
*p
)
887 struct ctldebug
*cdp
;
889 /* all sysctl names at this level are name and field */
891 return (ENOTDIR
); /* overloaded */
892 cdp
= debugvars
[name
[0]];
893 if (cdp
->debugname
== 0)
897 return (sysctl_rdstring(oldp
, oldlenp
, newp
, cdp
->debugname
));
898 case CTL_DEBUG_VALUE
:
899 return (sysctl_int(oldp
, oldlenp
, newp
, newlen
, cdp
->debugvar
));
908 * Validate parameters and get old / set new parameters
909 * for an integer-valued sysctl function.
912 sysctl_int(user_addr_t oldp
, size_t *oldlenp
,
913 user_addr_t newp
, size_t newlen
, int *valp
)
917 if (oldp
!= USER_ADDR_NULL
&& oldlenp
== NULL
)
919 if (oldp
&& *oldlenp
< sizeof(int))
921 if (newp
&& newlen
!= sizeof(int))
923 *oldlenp
= sizeof(int);
925 error
= copyout(valp
, oldp
, sizeof(int));
926 if (error
== 0 && newp
) {
927 error
= copyin(newp
, valp
, sizeof(int));
928 AUDIT_ARG(value
, *valp
);
934 * As above, but read-only.
937 sysctl_rdint(user_addr_t oldp
, size_t *oldlenp
, user_addr_t newp
, int val
)
941 if (oldp
!= USER_ADDR_NULL
&& oldlenp
== NULL
)
943 if (oldp
&& *oldlenp
< sizeof(int))
947 *oldlenp
= sizeof(int);
949 error
= copyout((caddr_t
)&val
, oldp
, sizeof(int));
954 * Validate parameters and get old / set new parameters
955 * for an quad(64bit)-valued sysctl function.
958 sysctl_quad(user_addr_t oldp
, size_t *oldlenp
,
959 user_addr_t newp
, size_t newlen
, quad_t
*valp
)
963 if (oldp
!= USER_ADDR_NULL
&& oldlenp
== NULL
)
965 if (oldp
&& *oldlenp
< sizeof(quad_t
))
967 if (newp
&& newlen
!= sizeof(quad_t
))
969 *oldlenp
= sizeof(quad_t
);
971 error
= copyout(valp
, oldp
, sizeof(quad_t
));
972 if (error
== 0 && newp
)
973 error
= copyin(newp
, valp
, sizeof(quad_t
));
978 * As above, but read-only.
981 sysctl_rdquad(oldp
, oldlenp
, newp
, val
)
989 if (oldp
!= USER_ADDR_NULL
&& oldlenp
== NULL
)
991 if (oldp
&& *oldlenp
< sizeof(quad_t
))
995 *oldlenp
= sizeof(quad_t
);
997 error
= copyout((caddr_t
)&val
, CAST_USER_ADDR_T(oldp
), sizeof(quad_t
));
1002 * Validate parameters and get old / set new parameters
1003 * for a string-valued sysctl function. Unlike sysctl_string, if you
1004 * give it a too small (but larger than 0 bytes) buffer, instead of
1005 * returning ENOMEM, it truncates the returned string to the buffer
1006 * size. This preserves the semantics of some library routines
1007 * implemented via sysctl, which truncate their returned data, rather
1008 * than simply returning an error. The returned string is always NUL
1012 sysctl_trstring(user_addr_t oldp
, size_t *oldlenp
,
1013 user_addr_t newp
, size_t newlen
, char *str
, int maxlen
)
1015 int len
, copylen
, error
= 0;
1017 if (oldp
!= USER_ADDR_NULL
&& oldlenp
== NULL
)
1019 copylen
= len
= strlen(str
) + 1;
1020 if (oldp
&& (len
< 0 || *oldlenp
< 1))
1022 if (oldp
&& (*oldlenp
< (size_t)len
))
1023 copylen
= *oldlenp
+ 1;
1024 if (newp
&& (maxlen
< 0 || newlen
>= (size_t)maxlen
))
1026 *oldlenp
= copylen
- 1; /* deal with NULL strings correctly */
1028 error
= copyout(str
, oldp
, copylen
);
1030 unsigned char c
= 0;
1033 error
= copyout((void *)&c
, oldp
, sizeof(char));
1036 if (error
== 0 && newp
) {
1037 error
= copyin(newp
, str
, newlen
);
1039 AUDIT_ARG(text
, (char *)str
);
1045 * Validate parameters and get old / set new parameters
1046 * for a string-valued sysctl function.
1049 sysctl_string(user_addr_t oldp
, size_t *oldlenp
,
1050 user_addr_t newp
, size_t newlen
, char *str
, int maxlen
)
1054 if (oldp
!= USER_ADDR_NULL
&& oldlenp
== NULL
)
1056 len
= strlen(str
) + 1;
1057 if (oldp
&& (len
< 0 || *oldlenp
< (size_t)len
))
1059 if (newp
&& (maxlen
< 0 || newlen
>= (size_t)maxlen
))
1061 *oldlenp
= len
-1; /* deal with NULL strings correctly */
1063 error
= copyout(str
, oldp
, len
);
1065 if (error
== 0 && newp
) {
1066 error
= copyin(newp
, str
, newlen
);
1068 AUDIT_ARG(text
, (char *)str
);
1074 * As above, but read-only.
1077 sysctl_rdstring(user_addr_t oldp
, size_t *oldlenp
,
1078 user_addr_t newp
, char *str
)
1082 if (oldp
!= USER_ADDR_NULL
&& oldlenp
== NULL
)
1084 len
= strlen(str
) + 1;
1085 if (oldp
&& *oldlenp
< (size_t)len
)
1091 error
= copyout(str
, oldp
, len
);
1096 * Validate parameters and get old / set new parameters
1097 * for a structure oriented sysctl function.
1100 sysctl_struct(user_addr_t oldp
, size_t *oldlenp
,
1101 user_addr_t newp
, size_t newlen
, void *sp
, int len
)
1105 if (oldp
!= USER_ADDR_NULL
&& oldlenp
== NULL
)
1107 if (oldp
&& (len
< 0 || *oldlenp
< (size_t)len
))
1109 if (newp
&& (len
< 0 || newlen
> (size_t)len
))
1113 error
= copyout(sp
, oldp
, len
);
1115 if (error
== 0 && newp
)
1116 error
= copyin(newp
, sp
, len
);
1121 * Validate parameters and get old parameters
1122 * for a structure oriented sysctl function.
1125 sysctl_rdstruct(user_addr_t oldp
, size_t *oldlenp
,
1126 user_addr_t newp
, void *sp
, int len
)
1130 if (oldp
!= USER_ADDR_NULL
&& oldlenp
== NULL
)
1132 if (oldp
&& (len
< 0 || *oldlenp
< (size_t)len
))
1138 error
= copyout(sp
, oldp
, len
);
1143 * Get file structures.
1146 sysctl_file(user_addr_t where
, size_t *sizep
)
1149 struct fileglob
*fg
;
1150 user_addr_t start
= where
;
1151 struct extern_file nef
;
1154 if (where
== USER_ADDR_NULL
) {
1156 * overestimate by 10 files
1158 *sizep
= sizeof(filehead
) + (nfiles
+ 10) * sizeof(struct extern_file
);
1163 * first copyout filehead
1165 if (buflen
< 0 || (size_t)buflen
< sizeof(filehead
)) {
1169 error
= copyout((caddr_t
)&filehead
, where
, sizeof(filehead
));
1172 buflen
-= sizeof(filehead
);
1173 where
+= sizeof(filehead
);
1176 * followed by an array of file structures
1178 for (fg
= filehead
.lh_first
; fg
!= 0; fg
= fg
->f_list
.le_next
) {
1179 if (buflen
< 0 || (size_t)buflen
< sizeof(struct extern_file
)) {
1180 *sizep
= where
- start
;
1183 nef
.f_list
.le_next
= (struct extern_file
*)fg
->f_list
.le_next
;
1184 nef
.f_list
.le_prev
= (struct extern_file
**)fg
->f_list
.le_prev
;
1185 nef
.f_flag
= (fg
->fg_flag
& FMASK
);
1186 nef
.f_type
= fg
->fg_type
;
1187 nef
.f_count
= fg
->fg_count
;
1188 nef
.f_msgcount
= fg
->fg_msgcount
;
1189 nef
.f_cred
= fg
->fg_cred
;
1190 nef
.f_ops
= fg
->fg_ops
;
1191 nef
.f_offset
= fg
->fg_offset
;
1192 nef
.f_data
= fg
->fg_data
;
1193 error
= copyout((caddr_t
)&nef
, where
, sizeof (struct extern_file
));
1196 buflen
-= sizeof(struct extern_file
);
1197 where
+= sizeof(struct extern_file
);
1199 *sizep
= where
- start
;
1204 * try over estimating by 5 procs
1206 #define KERN_PROCSLOP (5 * sizeof (struct kinfo_proc))
1209 sysctl_doproc(int *name
, u_int namelen
, user_addr_t where
, size_t *sizep
)
1212 user_addr_t dp
= where
;
1214 int buflen
= where
!= USER_ADDR_NULL
? *sizep
: 0;
1217 boolean_t is_64_bit
= FALSE
;
1218 struct kinfo_proc kproc
;
1219 struct user_kinfo_proc user_kproc
;
1223 if (namelen
!= 2 && !(namelen
== 1 && name
[0] == KERN_PROC_ALL
))
1225 p
= allproc
.lh_first
;
1227 is_64_bit
= proc_is64bit(current_proc());
1229 sizeof_kproc
= sizeof(user_kproc
);
1230 kprocp
= (caddr_t
) &user_kproc
;
1233 sizeof_kproc
= sizeof(kproc
);
1234 kprocp
= (caddr_t
) &kproc
;
1237 for (; p
!= 0; p
= p
->p_list
.le_next
) {
1239 * Skip embryonic processes.
1241 if (p
->p_stat
== SIDL
)
1244 * TODO - make more efficient (see notes below).
1250 /* could do this with just a lookup */
1251 if (p
->p_pid
!= (pid_t
)name
[1])
1255 case KERN_PROC_PGRP
:
1256 /* could do this by traversing pgrp */
1257 if (p
->p_pgrp
->pg_id
!= (pid_t
)name
[1])
1262 if ((p
->p_flag
& P_CONTROLT
) == 0 ||
1263 (p
->p_session
== NULL
) ||
1264 p
->p_session
->s_ttyp
== NULL
||
1265 p
->p_session
->s_ttyp
->t_dev
!= (dev_t
)name
[1])
1270 if ((p
->p_ucred
== NULL
) ||
1271 (kauth_cred_getuid(p
->p_ucred
) != (uid_t
)name
[1]))
1275 case KERN_PROC_RUID
:
1276 if ((p
->p_ucred
== NULL
) ||
1277 (p
->p_ucred
->cr_ruid
!= (uid_t
)name
[1]))
1281 if (buflen
>= sizeof_kproc
) {
1282 bzero(kprocp
, sizeof_kproc
);
1284 fill_user_proc(p
, (struct user_kinfo_proc
*) kprocp
);
1287 fill_proc(p
, (struct kinfo_proc
*) kprocp
);
1289 error
= copyout(kprocp
, dp
, sizeof_kproc
);
1293 buflen
-= sizeof_kproc
;
1295 needed
+= sizeof_kproc
;
1297 if (doingzomb
== 0) {
1298 p
= zombproc
.lh_first
;
1302 if (where
!= USER_ADDR_NULL
) {
1303 *sizep
= dp
- where
;
1304 if (needed
> *sizep
)
1307 needed
+= KERN_PROCSLOP
;
1314 * Fill in an eproc structure for the specified process.
1318 register struct proc
*p
;
1319 register struct eproc
*ep
;
1321 register struct tty
*tp
;
1325 ep
->e_sess
= p
->p_pgrp
->pg_session
;
1326 ep
->e_pgid
= p
->p_pgrp
->pg_id
;
1327 ep
->e_jobc
= p
->p_pgrp
->pg_jobc
;
1328 if (ep
->e_sess
&& ep
->e_sess
->s_ttyvp
)
1329 ep
->e_flag
= EPROC_CTTY
;
1331 ep
->e_sess
= (struct session
*)0;
1335 ep
->e_ppid
= (p
->p_pptr
) ? p
->p_pptr
->p_pid
: 0;
1336 /* Pre-zero the fake historical pcred */
1337 bzero(&ep
->e_pcred
, sizeof(struct _pcred
));
1339 /* XXX not ref-counted */
1341 /* A fake historical pcred */
1342 ep
->e_pcred
.p_ruid
= p
->p_ucred
->cr_ruid
;
1343 ep
->e_pcred
.p_svuid
= p
->p_ucred
->cr_svuid
;
1344 ep
->e_pcred
.p_rgid
= p
->p_ucred
->cr_rgid
;
1345 ep
->e_pcred
.p_svgid
= p
->p_ucred
->cr_svgid
;
1347 /* A fake historical *kauth_cred_t */
1348 ep
->e_ucred
.cr_ref
= p
->p_ucred
->cr_ref
;
1349 ep
->e_ucred
.cr_uid
= kauth_cred_getuid(p
->p_ucred
);
1350 ep
->e_ucred
.cr_ngroups
= p
->p_ucred
->cr_ngroups
;
1351 bcopy(p
->p_ucred
->cr_groups
, ep
->e_ucred
.cr_groups
, NGROUPS
*sizeof(gid_t
));
1354 if (p
->p_stat
== SIDL
|| p
->p_stat
== SZOMB
) {
1355 ep
->e_vm
.vm_tsize
= 0;
1356 ep
->e_vm
.vm_dsize
= 0;
1357 ep
->e_vm
.vm_ssize
= 0;
1359 ep
->e_vm
.vm_rssize
= 0;
1361 if ((p
->p_flag
& P_CONTROLT
) && (ep
->e_sess
) &&
1362 (tp
= ep
->e_sess
->s_ttyp
)) {
1363 ep
->e_tdev
= tp
->t_dev
;
1364 ep
->e_tpgid
= tp
->t_pgrp
? tp
->t_pgrp
->pg_id
: NO_PID
;
1365 ep
->e_tsess
= tp
->t_session
;
1370 ep
->e_flag
|= EPROC_SLEADER
;
1372 strncpy(ep
->e_wmesg
, p
->p_wmesg
, WMESGLEN
);
1373 ep
->e_xsize
= ep
->e_xrssize
= 0;
1374 ep
->e_xccount
= ep
->e_xswrss
= 0;
1378 * Fill in an LP64 version of eproc structure for the specified process.
1381 fill_user_eproc(register struct proc
*p
, register struct user_eproc
*ep
)
1383 register struct tty
*tp
;
1384 struct session
*sessionp
= NULL
;
1386 ep
->e_paddr
= CAST_USER_ADDR_T(p
);
1388 sessionp
= p
->p_pgrp
->pg_session
;
1389 ep
->e_sess
= CAST_USER_ADDR_T(sessionp
);
1390 ep
->e_pgid
= p
->p_pgrp
->pg_id
;
1391 ep
->e_jobc
= p
->p_pgrp
->pg_jobc
;
1393 if (sessionp
->s_ttyvp
)
1394 ep
->e_flag
= EPROC_CTTY
;
1397 ep
->e_sess
= USER_ADDR_NULL
;
1401 ep
->e_ppid
= (p
->p_pptr
) ? p
->p_pptr
->p_pid
: 0;
1402 /* Pre-zero the fake historical pcred */
1403 bzero(&ep
->e_pcred
, sizeof(ep
->e_pcred
));
1405 /* XXX not ref-counted */
1407 /* A fake historical pcred */
1408 ep
->e_pcred
.p_ruid
= p
->p_ucred
->cr_ruid
;
1409 ep
->e_pcred
.p_svuid
= p
->p_ucred
->cr_svuid
;
1410 ep
->e_pcred
.p_rgid
= p
->p_ucred
->cr_rgid
;
1411 ep
->e_pcred
.p_svgid
= p
->p_ucred
->cr_svgid
;
1413 /* A fake historical *kauth_cred_t */
1414 ep
->e_ucred
.cr_ref
= p
->p_ucred
->cr_ref
;
1415 ep
->e_ucred
.cr_uid
= kauth_cred_getuid(p
->p_ucred
);
1416 ep
->e_ucred
.cr_ngroups
= p
->p_ucred
->cr_ngroups
;
1417 bcopy(p
->p_ucred
->cr_groups
, ep
->e_ucred
.cr_groups
, NGROUPS
*sizeof(gid_t
));
1420 if (p
->p_stat
== SIDL
|| p
->p_stat
== SZOMB
) {
1421 ep
->e_vm
.vm_tsize
= 0;
1422 ep
->e_vm
.vm_dsize
= 0;
1423 ep
->e_vm
.vm_ssize
= 0;
1425 ep
->e_vm
.vm_rssize
= 0;
1427 if ((p
->p_flag
& P_CONTROLT
) && (sessionp
) &&
1428 (tp
= sessionp
->s_ttyp
)) {
1429 ep
->e_tdev
= tp
->t_dev
;
1430 ep
->e_tpgid
= tp
->t_pgrp
? tp
->t_pgrp
->pg_id
: NO_PID
;
1431 ep
->e_tsess
= CAST_USER_ADDR_T(tp
->t_session
);
1436 ep
->e_flag
|= EPROC_SLEADER
;
1438 strncpy(ep
->e_wmesg
, p
->p_wmesg
, WMESGLEN
);
1439 ep
->e_xsize
= ep
->e_xrssize
= 0;
1440 ep
->e_xccount
= ep
->e_xswrss
= 0;
1444 * Fill in an eproc structure for the specified process.
1447 fill_externproc(p
, exp
)
1448 register struct proc
*p
;
1449 register struct extern_proc
*exp
;
1451 exp
->p_forw
= exp
->p_back
= NULL
;
1453 exp
->p_starttime
= p
->p_stats
->p_start
;
1454 exp
->p_vmspace
= NULL
;
1455 exp
->p_sigacts
= p
->p_sigacts
;
1456 exp
->p_flag
= p
->p_flag
;
1457 exp
->p_stat
= p
->p_stat
;
1458 exp
->p_pid
= p
->p_pid
;
1459 exp
->p_oppid
= p
->p_oppid
;
1460 exp
->p_dupfd
= p
->p_dupfd
;
1462 exp
->user_stack
= CAST_DOWN(caddr_t
, p
->user_stack
);
1463 exp
->exit_thread
= p
->exit_thread
;
1464 exp
->p_debugger
= p
->p_debugger
;
1465 exp
->sigwait
= p
->sigwait
;
1467 exp
->p_estcpu
= p
->p_estcpu
;
1468 exp
->p_cpticks
= p
->p_cpticks
;
1469 exp
->p_pctcpu
= p
->p_pctcpu
;
1470 exp
->p_wchan
= p
->p_wchan
;
1471 exp
->p_wmesg
= p
->p_wmesg
;
1472 exp
->p_swtime
= p
->p_swtime
;
1473 exp
->p_slptime
= p
->p_slptime
;
1474 bcopy(&p
->p_realtimer
, &exp
->p_realtimer
,sizeof(struct itimerval
));
1475 bcopy(&p
->p_rtime
, &exp
->p_rtime
,sizeof(struct timeval
));
1476 exp
->p_uticks
= p
->p_uticks
;
1477 exp
->p_sticks
= p
->p_sticks
;
1478 exp
->p_iticks
= p
->p_iticks
;
1479 exp
->p_traceflag
= p
->p_traceflag
;
1480 exp
->p_tracep
= p
->p_tracep
;
1481 exp
->p_siglist
= 0 ; /* No longer relevant */
1482 exp
->p_textvp
= p
->p_textvp
;
1483 exp
->p_holdcnt
= 0 ;
1484 exp
->p_sigmask
= 0 ; /* no longer avaialable */
1485 exp
->p_sigignore
= p
->p_sigignore
;
1486 exp
->p_sigcatch
= p
->p_sigcatch
;
1487 exp
->p_priority
= p
->p_priority
;
1488 exp
->p_usrpri
= p
->p_usrpri
;
1489 exp
->p_nice
= p
->p_nice
;
1490 bcopy(&p
->p_comm
, &exp
->p_comm
,MAXCOMLEN
);
1491 exp
->p_comm
[MAXCOMLEN
] = '\0';
1492 exp
->p_pgrp
= p
->p_pgrp
;
1494 exp
->p_xstat
= p
->p_xstat
;
1495 exp
->p_acflag
= p
->p_acflag
;
1496 exp
->p_ru
= p
->p_ru
; /* XXX may be NULL */
1500 * Fill in an LP64 version of extern_proc structure for the specified process.
1503 fill_user_externproc(register struct proc
*p
, register struct user_extern_proc
*exp
)
1505 exp
->p_forw
= exp
->p_back
= USER_ADDR_NULL
;
1507 exp
->p_starttime
.tv_sec
= p
->p_stats
->p_start
.tv_sec
;
1508 exp
->p_starttime
.tv_usec
= p
->p_stats
->p_start
.tv_usec
;
1510 exp
->p_vmspace
= USER_ADDR_NULL
;
1511 exp
->p_sigacts
= CAST_USER_ADDR_T(p
->p_sigacts
);
1512 exp
->p_flag
= p
->p_flag
;
1513 exp
->p_stat
= p
->p_stat
;
1514 exp
->p_pid
= p
->p_pid
;
1515 exp
->p_oppid
= p
->p_oppid
;
1516 exp
->p_dupfd
= p
->p_dupfd
;
1518 exp
->user_stack
= p
->user_stack
;
1519 exp
->exit_thread
= CAST_USER_ADDR_T(p
->exit_thread
);
1520 exp
->p_debugger
= p
->p_debugger
;
1521 exp
->sigwait
= p
->sigwait
;
1523 exp
->p_estcpu
= p
->p_estcpu
;
1524 exp
->p_cpticks
= p
->p_cpticks
;
1525 exp
->p_pctcpu
= p
->p_pctcpu
;
1526 exp
->p_wchan
= CAST_USER_ADDR_T(p
->p_wchan
);
1527 exp
->p_wmesg
= CAST_USER_ADDR_T(p
->p_wmesg
);
1528 exp
->p_swtime
= p
->p_swtime
;
1529 exp
->p_slptime
= p
->p_slptime
;
1530 exp
->p_realtimer
.it_interval
.tv_sec
= p
->p_realtimer
.it_interval
.tv_sec
;
1531 exp
->p_realtimer
.it_interval
.tv_usec
= p
->p_realtimer
.it_interval
.tv_usec
;
1532 exp
->p_realtimer
.it_value
.tv_sec
= p
->p_realtimer
.it_value
.tv_sec
;
1533 exp
->p_realtimer
.it_value
.tv_usec
= p
->p_realtimer
.it_value
.tv_usec
;
1534 exp
->p_rtime
.tv_sec
= p
->p_rtime
.tv_sec
;
1535 exp
->p_rtime
.tv_usec
= p
->p_rtime
.tv_usec
;
1536 exp
->p_uticks
= p
->p_uticks
;
1537 exp
->p_sticks
= p
->p_sticks
;
1538 exp
->p_iticks
= p
->p_iticks
;
1539 exp
->p_traceflag
= p
->p_traceflag
;
1540 exp
->p_tracep
= CAST_USER_ADDR_T(p
->p_tracep
);
1541 exp
->p_siglist
= 0 ; /* No longer relevant */
1542 exp
->p_textvp
= CAST_USER_ADDR_T(p
->p_textvp
);
1543 exp
->p_holdcnt
= 0 ;
1544 exp
->p_sigmask
= 0 ; /* no longer avaialable */
1545 exp
->p_sigignore
= p
->p_sigignore
;
1546 exp
->p_sigcatch
= p
->p_sigcatch
;
1547 exp
->p_priority
= p
->p_priority
;
1548 exp
->p_usrpri
= p
->p_usrpri
;
1549 exp
->p_nice
= p
->p_nice
;
1550 bcopy(&p
->p_comm
, &exp
->p_comm
,MAXCOMLEN
);
1551 exp
->p_comm
[MAXCOMLEN
] = '\0';
1552 exp
->p_pgrp
= CAST_USER_ADDR_T(p
->p_pgrp
);
1553 exp
->p_addr
= USER_ADDR_NULL
;
1554 exp
->p_xstat
= p
->p_xstat
;
1555 exp
->p_acflag
= p
->p_acflag
;
1556 exp
->p_ru
= CAST_USER_ADDR_T(p
->p_ru
); /* XXX may be NULL */
1561 register struct proc
*p
;
1562 register struct kinfo_proc
*kp
;
1564 fill_externproc(p
, &kp
->kp_proc
);
1565 fill_eproc(p
, &kp
->kp_eproc
);
1569 fill_user_proc(register struct proc
*p
, register struct user_kinfo_proc
*kp
)
1571 fill_user_externproc(p
, &kp
->kp_proc
);
1572 fill_user_eproc(p
, &kp
->kp_eproc
);
1576 kdebug_ops(int *name
, u_int namelen
, user_addr_t where
,
1577 size_t *sizep
, struct proc
*p
)
1581 ret
= suser(kauth_cred_get(), &p
->p_acflag
);
1598 case KERN_KDSETRTCDEC
:
1600 case KERN_KDGETENTROPY
:
1601 ret
= kdbg_control(name
, namelen
, where
, sizep
);
1610 extern int pcsamples_control(int *name
, u_int namelen
, user_addr_t where
,
1614 pcsamples_ops(int *name
, u_int namelen
, user_addr_t where
,
1615 size_t *sizep
, struct proc
*p
)
1619 ret
= suser(kauth_cred_get(), &p
->p_acflag
);
1624 case KERN_PCDISABLE
:
1628 case KERN_PCREADBUF
:
1632 ret
= pcsamples_control(name
, namelen
, where
, sizep
);
1642 * Return the top *sizep bytes of the user stack, or the entire area of the
1643 * user stack down through the saved exec_path, whichever is smaller.
1646 sysctl_procargs(int *name
, u_int namelen
, user_addr_t where
,
1647 size_t *sizep
, struct proc
*cur_proc
)
1649 return sysctl_procargsx( name
, namelen
, where
, sizep
, cur_proc
, 0);
1653 sysctl_procargs2(int *name
, u_int namelen
, user_addr_t where
,
1654 size_t *sizep
, struct proc
*cur_proc
)
1656 return sysctl_procargsx( name
, namelen
, where
, sizep
, cur_proc
, 1);
1660 sysctl_procargsx(int *name
, __unused u_int namelen
, user_addr_t where
,
1661 size_t *sizep
, struct proc
*cur_proc
, int argc_yes
)
1664 int buflen
= where
!= USER_ADDR_NULL
? *sizep
: 0;
1666 struct vm_map
*proc_map
;
1669 user_addr_t arg_addr
;
1673 vm_offset_t copy_start
, copy_end
;
1678 buflen
-= sizeof(int); /* reserve first word to return argc */
1680 /* we only care about buflen when where (oldp from sysctl) is not NULL. */
1681 /* when where (oldp from sysctl) is NULL and sizep (oldlenp from sysctl */
1682 /* is not NULL then the caller wants us to return the length needed to */
1683 /* hold the data we would return */
1684 if (where
!= USER_ADDR_NULL
&& (buflen
<= 0 || buflen
> ARG_MAX
)) {
1690 * Lookup process by pid
1699 * Copy the top N bytes of the stack.
1700 * On all machines we have so far, the stack grows
1703 * If the user expects no more than N bytes of
1704 * argument list, use that as a guess for the
1711 if (where
== USER_ADDR_NULL
) {
1712 /* caller only wants to know length of proc args data */
1716 size
= p
->p_argslen
;
1718 size
+= sizeof(int);
1722 * old PROCARGS will return the executable's path and plus some
1723 * extra space for work alignment and data tags
1725 size
+= PATH_MAX
+ (6 * sizeof(int));
1727 size
+= (size
& (sizeof(int) - 1)) ? (sizeof(int) - (size
& (sizeof(int) - 1))) : 0;
1732 if ((kauth_cred_getuid(p
->p_ucred
) != kauth_cred_getuid(kauth_cred_get()))
1733 && suser(kauth_cred_get(), &cur_proc
->p_acflag
))
1736 if ((u_int
)arg_size
> p
->p_argslen
)
1737 arg_size
= round_page(p
->p_argslen
);
1739 arg_addr
= p
->user_stack
- arg_size
;
1743 * Before we can block (any VM code), make another
1744 * reference to the map to keep it alive. We do
1745 * that by getting a reference on the task itself.
1752 * Once we have a task reference we can convert that into a
1753 * map reference, which we will use in the calls below. The
1754 * task/process may change its map after we take this reference
1755 * (see execve), but the worst that will happen then is a return
1756 * of stale info (which is always a possibility).
1758 task_reference(task
);
1759 proc_map
= get_task_map_reference(task
);
1760 task_deallocate(task
);
1761 if (proc_map
== NULL
)
1765 ret
= kmem_alloc(kernel_map
, ©_start
, round_page(arg_size
));
1766 if (ret
!= KERN_SUCCESS
) {
1767 vm_map_deallocate(proc_map
);
1771 copy_end
= round_page(copy_start
+ arg_size
);
1773 if( vm_map_copyin(proc_map
, (vm_map_address_t
)arg_addr
,
1774 (vm_map_size_t
)arg_size
, FALSE
, &tmp
) != KERN_SUCCESS
) {
1775 vm_map_deallocate(proc_map
);
1776 kmem_free(kernel_map
, copy_start
,
1777 round_page(arg_size
));
1782 * Now that we've done the copyin from the process'
1783 * map, we can release the reference to it.
1785 vm_map_deallocate(proc_map
);
1787 if( vm_map_copy_overwrite(kernel_map
,
1788 (vm_map_address_t
)copy_start
,
1789 tmp
, FALSE
) != KERN_SUCCESS
) {
1790 kmem_free(kernel_map
, copy_start
,
1791 round_page(arg_size
));
1795 if (arg_size
> p
->p_argslen
) {
1796 data
= (caddr_t
) (copy_end
- p
->p_argslen
);
1797 size
= p
->p_argslen
;
1799 data
= (caddr_t
) (copy_end
- arg_size
);
1804 /* Put processes argc as the first word in the copyout buffer */
1805 suword(where
, p
->p_argc
);
1806 error
= copyout(data
, (where
+ sizeof(int)), size
);
1807 size
+= sizeof(int);
1809 error
= copyout(data
, where
, size
);
1812 * Make the old PROCARGS work to return the executable's path
1813 * But, only if there is enough space in the provided buffer
1815 * on entry: data [possibily] points to the beginning of the path
1817 * Note: we keep all pointers&sizes aligned to word boundries
1819 if ( (! error
) && (buflen
> 0 && (u_int
)buflen
> p
->p_argslen
) )
1821 int binPath_sz
, alignedBinPath_sz
= 0;
1822 int extraSpaceNeeded
, addThis
;
1823 user_addr_t placeHere
;
1824 char * str
= (char *) data
;
1827 /* Some apps are really bad about messing up their stacks
1828 So, we have to be extra careful about getting the length
1829 of the executing binary. If we encounter an error, we bail.
1832 /* Limit ourselves to PATH_MAX paths */
1833 if ( max_len
> PATH_MAX
) max_len
= PATH_MAX
;
1837 while ( (binPath_sz
< max_len
-1) && (*str
++ != 0) )
1840 /* If we have a NUL terminator, copy it, too */
1841 if (binPath_sz
< max_len
-1) binPath_sz
+= 1;
1843 /* Pre-Flight the space requiremnts */
1845 /* Account for the padding that fills out binPath to the next word */
1846 alignedBinPath_sz
+= (binPath_sz
& (sizeof(int)-1)) ? (sizeof(int)-(binPath_sz
& (sizeof(int)-1))) : 0;
1848 placeHere
= where
+ size
;
1850 /* Account for the bytes needed to keep placeHere word aligned */
1851 addThis
= (placeHere
& (sizeof(int)-1)) ? (sizeof(int)-(placeHere
& (sizeof(int)-1))) : 0;
1853 /* Add up all the space that is needed */
1854 extraSpaceNeeded
= alignedBinPath_sz
+ addThis
+ binPath_sz
+ (4 * sizeof(int));
1856 /* is there is room to tack on argv[0]? */
1857 if ( (buflen
& ~(sizeof(int)-1)) >= ( p
->p_argslen
+ extraSpaceNeeded
))
1859 placeHere
+= addThis
;
1860 suword(placeHere
, 0);
1861 placeHere
+= sizeof(int);
1862 suword(placeHere
, 0xBFFF0000);
1863 placeHere
+= sizeof(int);
1864 suword(placeHere
, 0);
1865 placeHere
+= sizeof(int);
1866 error
= copyout(data
, placeHere
, binPath_sz
);
1869 placeHere
+= binPath_sz
;
1870 suword(placeHere
, 0);
1871 size
+= extraSpaceNeeded
;
1877 if (copy_start
!= (vm_offset_t
) 0) {
1878 kmem_free(kernel_map
, copy_start
, copy_end
- copy_start
);
1884 if (where
!= USER_ADDR_NULL
)
1891 * Validate parameters and get old / set new parameters
1892 * for max number of concurrent aio requests. Makes sure
1893 * the system wide limit is greater than the per process
1897 sysctl_aiomax(user_addr_t oldp
, size_t *oldlenp
, user_addr_t newp
, size_t newlen
)
1902 if ( oldp
&& *oldlenp
< sizeof(int) )
1904 if ( newp
&& newlen
!= sizeof(int) )
1907 *oldlenp
= sizeof(int);
1909 error
= copyout( &aio_max_requests
, oldp
, sizeof(int) );
1910 if ( error
== 0 && newp
)
1911 error
= copyin( newp
, &new_value
, sizeof(int) );
1912 if ( error
== 0 && newp
) {
1913 if ( new_value
>= aio_max_requests_per_process
)
1914 aio_max_requests
= new_value
;
1920 } /* sysctl_aiomax */
1924 * Validate parameters and get old / set new parameters
1925 * for max number of concurrent aio requests per process.
1926 * Makes sure per process limit is less than the system wide
1930 sysctl_aioprocmax(user_addr_t oldp
, size_t *oldlenp
, user_addr_t newp
, size_t newlen
)
1935 if ( oldp
&& *oldlenp
< sizeof(int) )
1937 if ( newp
&& newlen
!= sizeof(int) )
1940 *oldlenp
= sizeof(int);
1942 error
= copyout( &aio_max_requests_per_process
, oldp
, sizeof(int) );
1943 if ( error
== 0 && newp
)
1944 error
= copyin( newp
, &new_value
, sizeof(int) );
1945 if ( error
== 0 && newp
) {
1946 if ( new_value
<= aio_max_requests
&& new_value
>= AIO_LISTIO_MAX
)
1947 aio_max_requests_per_process
= new_value
;
1953 } /* sysctl_aioprocmax */
1957 * Validate parameters and get old / set new parameters
1958 * for max number of async IO worker threads.
1959 * We only allow an increase in the number of worker threads.
1962 sysctl_aiothreads(user_addr_t oldp
, size_t *oldlenp
, user_addr_t newp
, size_t newlen
)
1967 if ( oldp
&& *oldlenp
< sizeof(int) )
1969 if ( newp
&& newlen
!= sizeof(int) )
1972 *oldlenp
= sizeof(int);
1974 error
= copyout( &aio_worker_threads
, oldp
, sizeof(int) );
1975 if ( error
== 0 && newp
)
1976 error
= copyin( newp
, &new_value
, sizeof(int) );
1977 if ( error
== 0 && newp
) {
1978 if (new_value
> aio_worker_threads
) {
1979 _aio_create_worker_threads( (new_value
- aio_worker_threads
) );
1980 aio_worker_threads
= new_value
;
1987 } /* sysctl_aiothreads */
1991 * Validate parameters and get old / set new parameters
1992 * for max number of processes per UID.
1993 * Makes sure per UID limit is less than the system wide limit.
1996 sysctl_maxprocperuid(user_addr_t oldp
, size_t *oldlenp
,
1997 user_addr_t newp
, size_t newlen
)
2002 if ( oldp
!= USER_ADDR_NULL
&& *oldlenp
< sizeof(int) )
2004 if ( newp
!= USER_ADDR_NULL
&& newlen
!= sizeof(int) )
2007 *oldlenp
= sizeof(int);
2008 if ( oldp
!= USER_ADDR_NULL
)
2009 error
= copyout( &maxprocperuid
, oldp
, sizeof(int) );
2010 if ( error
== 0 && newp
!= USER_ADDR_NULL
) {
2011 error
= copyin( newp
, &new_value
, sizeof(int) );
2013 AUDIT_ARG(value
, new_value
);
2014 if ( new_value
<= maxproc
&& new_value
> 0 )
2015 maxprocperuid
= new_value
;
2024 } /* sysctl_maxprocperuid */
2028 * Validate parameters and get old / set new parameters
2029 * for max number of files per process.
2030 * Makes sure per process limit is less than the system-wide limit.
2033 sysctl_maxfilesperproc(user_addr_t oldp
, size_t *oldlenp
,
2034 user_addr_t newp
, size_t newlen
)
2039 if ( oldp
!= USER_ADDR_NULL
&& *oldlenp
< sizeof(int) )
2041 if ( newp
!= USER_ADDR_NULL
&& newlen
!= sizeof(int) )
2044 *oldlenp
= sizeof(int);
2045 if ( oldp
!= USER_ADDR_NULL
)
2046 error
= copyout( &maxfilesperproc
, oldp
, sizeof(int) );
2047 if ( error
== 0 && newp
!= USER_ADDR_NULL
) {
2048 error
= copyin( newp
, &new_value
, sizeof(int) );
2050 AUDIT_ARG(value
, new_value
);
2051 if ( new_value
< maxfiles
&& new_value
> 0 )
2052 maxfilesperproc
= new_value
;
2061 } /* sysctl_maxfilesperproc */
2065 * Validate parameters and get old / set new parameters
2066 * for the system-wide limit on the max number of processes.
2067 * Makes sure the system-wide limit is less than the configured hard
2068 * limit set at kernel compilation.
2071 sysctl_maxproc(user_addr_t oldp
, size_t *oldlenp
,
2072 user_addr_t newp
, size_t newlen
)
2077 if ( oldp
!= USER_ADDR_NULL
&& *oldlenp
< sizeof(int) )
2079 if ( newp
!= USER_ADDR_NULL
&& newlen
!= sizeof(int) )
2082 *oldlenp
= sizeof(int);
2083 if ( oldp
!= USER_ADDR_NULL
)
2084 error
= copyout( &maxproc
, oldp
, sizeof(int) );
2085 if ( error
== 0 && newp
!= USER_ADDR_NULL
) {
2086 error
= copyin( newp
, &new_value
, sizeof(int) );
2088 AUDIT_ARG(value
, new_value
);
2089 if ( new_value
<= hard_maxproc
&& new_value
> 0 )
2090 maxproc
= new_value
;
2099 } /* sysctl_maxproc */