2 * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
25 /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
27 * Copyright (c) 1982, 1986, 1989, 1993
28 * The Regents of the University of California. All rights reserved.
30 * This code is derived from software contributed to Berkeley by
31 * Mike Karels at Berkeley Software Design, Inc.
33 * Redistribution and use in source and binary forms, with or without
34 * modification, are permitted provided that the following conditions
36 * 1. Redistributions of source code must retain the above copyright
37 * notice, this list of conditions and the following disclaimer.
38 * 2. Redistributions in binary form must reproduce the above copyright
39 * notice, this list of conditions and the following disclaimer in the
40 * documentation and/or other materials provided with the distribution.
41 * 3. All advertising materials mentioning features or use of this software
42 * must display the following acknowledgement:
43 * This product includes software developed by the University of
44 * California, Berkeley and its contributors.
45 * 4. Neither the name of the University nor the names of its contributors
46 * may be used to endorse or promote products derived from this software
47 * without specific prior written permission.
49 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
50 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
51 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
53 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
61 * @(#)kern_sysctl.c 8.4 (Berkeley) 4/14/94
68 #include <sys/param.h>
69 #include <sys/systm.h>
70 #include <sys/kernel.h>
71 #include <sys/malloc.h>
74 #include <sys/vnode.h>
75 #include <sys/unistd.h>
77 #include <sys/ioctl.h>
79 #include <sys/disklabel.h>
81 #include <sys/sysctl.h>
83 #include <mach/machine.h>
84 #include <mach/mach_types.h>
85 #include <mach/vm_param.h>
86 #include <kern/task.h>
87 #include <vm/vm_kern.h>
88 #include <mach/host_info.h>
90 extern vm_map_t bsd_pageable_map
;
92 #include <sys/mount.h>
93 #include <sys/kdebug.h>
95 #include <IOKit/IOPlatformExpert.h>
96 #include <pexpert/pexpert.h>
99 #include <ppc/machine_routines.h>
102 sysctlfn kern_sysctl
;
104 sysctlfn debug_sysctl
;
106 extern sysctlfn vm_sysctl
;
107 extern sysctlfn vfs_sysctl
;
108 extern sysctlfn net_sysctl
;
109 extern sysctlfn cpu_sysctl
;
113 userland_sysctl(struct proc
*p
, int *name
, u_int namelen
, void *old
, size_t
114 *oldlenp
, int inkernel
, void *new, size_t newlen
, size_t *retval
);
117 fill_proc(struct proc
*p
,struct kinfo_proc
*kp
, int doingzomb
);
120 fill_externproc(struct proc
*p
, struct extern_proc
*exp
);
125 * temporary location for vm_sysctl. This should be machine independant
128 vm_sysctl(name
, namelen
, oldp
, oldlenp
, newp
, newlen
, p
)
137 extern uint32_t mach_factor
[3];
138 struct loadavg loadinfo
;
142 return (sysctl_struct(oldp
, oldlenp
, newp
, newlen
,
143 &averunnable
, sizeof(struct loadavg
)));
145 loadinfo
.ldavg
[0] = mach_factor
[0];
146 loadinfo
.ldavg
[1] = mach_factor
[1];
147 loadinfo
.ldavg
[2] = mach_factor
[2];
148 loadinfo
.fscale
= LSCALE
;
149 return (sysctl_struct(oldp
, oldlenp
, newp
, newlen
,
150 &loadinfo
, sizeof(struct loadavg
)));
165 static struct sysctl_lock
{
171 struct __sysctl_args
{
180 __sysctl(p
, uap
, retval
)
182 register struct __sysctl_args
*uap
;
185 int error
, dolock
= 1;
186 size_t savelen
, oldlen
= 0;
188 int name
[CTL_MAXNAME
];
193 * all top-level sysctl names are non-terminal
195 if (uap
->namelen
> CTL_MAXNAME
|| uap
->namelen
< 2)
198 copyin(uap
->name
, &name
, uap
->namelen
* sizeof(int)))
201 /* CTL_UNSPEC is used to get oid to AUTO_OID */
203 && ((name
[0] == CTL_KERN
204 && !(name
[1] == KERN_IPC
|| name
[1] == KERN_PANICINFO
))
205 || (name
[0] == CTL_HW
)
206 || (name
[0] == CTL_VM
)
207 || (name
[0] == CTL_VFS
))
208 && (error
= suser(p
->p_ucred
, &p
->p_acflag
)))
214 if ((name
[1] != KERN_VNODE
) && (name
[1] != KERN_FILE
)
215 && (name
[1] != KERN_PROC
))
235 (error
= copyin(uap
->oldlenp
, &oldlen
, sizeof(oldlen
))))
238 if (uap
->old
!= NULL
) {
239 if (!useracc(uap
->old
, oldlen
, B_WRITE
))
242 /* The pc sampling mechanism does not need to take this lock */
243 if ((name
[1] != KERN_PCSAMPLES
) &&
244 (!((name
[1] == KERN_KDEBUG
) && (name
[2] == KERN_KDGETENTROPY
)))) {
245 while (memlock
.sl_lock
) {
247 sleep((caddr_t
)&memlock
, PRIBIO
+1);
253 if (dolock
&& oldlen
&& (error
= vslock(uap
->old
, oldlen
))) {
254 if ((name
[1] != KERN_PCSAMPLES
) &&
255 (! ((name
[1] == KERN_KDEBUG
) && (name
[2] == KERN_KDGETENTROPY
)))) {
257 if (memlock
.sl_want
) {
259 wakeup((caddr_t
)&memlock
);
268 error
= (*fn
)(name
+ 1, uap
->namelen
- 1, uap
->old
,
269 &oldlen
, uap
->new, uap
->newlen
, p
);
273 if ( (name
[0] != CTL_VFS
) && (error
== EOPNOTSUPP
))
274 error
= userland_sysctl(p
, name
, uap
->namelen
,
275 uap
->old
, uap
->oldlenp
, 0,
276 uap
->new, uap
->newlen
, &oldlen
);
278 if (uap
->old
!= NULL
) {
279 if (dolock
&& savelen
) {
280 error1
= vsunlock(uap
->old
, savelen
, B_WRITE
);
281 if (!error
&& error1
)
284 if (name
[1] != KERN_PCSAMPLES
) {
286 if (memlock
.sl_want
) {
288 wakeup((caddr_t
)&memlock
);
292 if ((error
) && (error
!= ENOMEM
))
296 i
= copyout(&oldlen
, uap
->oldlenp
, sizeof(oldlen
));
305 * Attributes stored in the kernel.
307 extern char hostname
[MAXHOSTNAMELEN
]; /* defined in bsd/kern/init_main.c */
308 extern int hostnamelen
;
309 extern char domainname
[MAXHOSTNAMELEN
];
310 extern int domainnamelen
;
313 int securelevel
= -1;
318 extern int get_kernel_symfile( struct proc
*, char **);
319 extern int sysctl_dopanicinfo(int *, u_int
, void *, size_t *,
320 void *, size_t, struct proc
*);
323 * kernel related system variables.
326 kern_sysctl(name
, namelen
, oldp
, oldlenp
, newp
, newlen
, p
)
335 int error
, level
, inthostid
;
336 unsigned int oldval
=0;
338 extern char ostype
[], osrelease
[], version
[];
339 extern int netboot_root();
341 /* all sysctl names not listed below are terminal at this level */
343 && !(name
[0] == KERN_PROC
344 || name
[0] == KERN_PROF
345 || name
[0] == KERN_KDEBUG
346 || name
[0] == KERN_PROCARGS
347 || name
[0] == KERN_PCSAMPLES
348 || name
[0] == KERN_IPC
349 || name
[0] == KERN_SYSV
350 || name
[0] == KERN_PANICINFO
)
352 return (ENOTDIR
); /* overloaded */
356 return (sysctl_rdstring(oldp
, oldlenp
, newp
, ostype
));
358 return (sysctl_rdstring(oldp
, oldlenp
, newp
, osrelease
));
360 return (sysctl_rdint(oldp
, oldlenp
, newp
, BSD
));
362 return (sysctl_rdstring(oldp
, oldlenp
, newp
, version
));
364 oldval
= desiredvnodes
;
365 error
= sysctl_int(oldp
, oldlenp
, newp
,
366 newlen
, &desiredvnodes
);
367 reset_vmobjectcache(oldval
, desiredvnodes
);
370 return (sysctl_int(oldp
, oldlenp
, newp
, newlen
, &maxproc
));
372 return (sysctl_int(oldp
, oldlenp
, newp
, newlen
, &maxfiles
));
374 return (sysctl_rdint(oldp
, oldlenp
, newp
, ARG_MAX
));
377 if ((error
= sysctl_int(oldp
, oldlenp
, newp
, newlen
, &level
)) ||
380 if (level
< securelevel
&& p
->p_pid
!= 1)
385 error
= sysctl_string(oldp
, oldlenp
, newp
, newlen
,
386 hostname
, sizeof(hostname
));
388 hostnamelen
= newlen
;
390 case KERN_DOMAINNAME
:
391 error
= sysctl_string(oldp
, oldlenp
, newp
, newlen
,
392 domainname
, sizeof(domainname
));
394 domainnamelen
= newlen
;
397 inthostid
= hostid
; /* XXX assumes sizeof long <= sizeof int */
398 error
= sysctl_int(oldp
, oldlenp
, newp
, newlen
, &inthostid
);
402 return (sysctl_clockrate(oldp
, oldlenp
));
404 return (sysctl_rdstruct(oldp
, oldlenp
, newp
, &boottime
,
405 sizeof(struct timeval
)));
407 return (sysctl_vnode(oldp
, oldlenp
));
409 return (sysctl_doproc(name
+ 1, namelen
- 1, oldp
, oldlenp
));
411 return (sysctl_file(oldp
, oldlenp
));
414 return (sysctl_doprof(name
+ 1, namelen
- 1, oldp
, oldlenp
,
418 return (sysctl_rdint(oldp
, oldlenp
, newp
, _POSIX_VERSION
));
420 return (sysctl_rdint(oldp
, oldlenp
, newp
, NGROUPS_MAX
));
421 case KERN_JOB_CONTROL
:
422 return (sysctl_rdint(oldp
, oldlenp
, newp
, 1));
424 #ifdef _POSIX_SAVED_IDS
425 return (sysctl_rdint(oldp
, oldlenp
, newp
, 1));
427 return (sysctl_rdint(oldp
, oldlenp
, newp
, 0));
430 return (kdebug_ops(name
+ 1, namelen
- 1, oldp
, oldlenp
, p
));
432 return (pcsamples_ops(name
+ 1, namelen
- 1, oldp
, oldlenp
, p
));
434 /* new one as it does not use kinfo_proc */
435 return (sysctl_procargs(name
+ 1, namelen
- 1, oldp
, oldlenp
, p
));
437 error
= get_kernel_symfile( p
, &str
);
440 return (sysctl_rdstring(oldp
, oldlenp
, newp
, str
));
442 return (sysctl_rdint(oldp
, oldlenp
, newp
, netboot_root()));
444 return(sysctl_dopanicinfo(name
+ 1, namelen
- 1, oldp
, oldlenp
,
454 * Debugging related system variables.
458 #endif /* DIAGNOSTIC */
459 struct ctldebug debug0
, debug1
;
460 struct ctldebug debug2
, debug3
, debug4
;
461 struct ctldebug debug5
, debug6
, debug7
, debug8
, debug9
;
462 struct ctldebug debug10
, debug11
, debug12
, debug13
, debug14
;
463 struct ctldebug debug15
, debug16
, debug17
, debug18
, debug19
;
464 static struct ctldebug
*debugvars
[CTL_DEBUG_MAXID
] = {
465 &debug0
, &debug1
, &debug2
, &debug3
, &debug4
,
466 &debug5
, &debug6
, &debug7
, &debug8
, &debug9
,
467 &debug10
, &debug11
, &debug12
, &debug13
, &debug14
,
468 &debug15
, &debug16
, &debug17
, &debug18
, &debug19
,
471 debug_sysctl(name
, namelen
, oldp
, oldlenp
, newp
, newlen
, p
)
480 struct ctldebug
*cdp
;
482 /* all sysctl names at this level are name and field */
484 return (ENOTDIR
); /* overloaded */
485 cdp
= debugvars
[name
[0]];
486 if (cdp
->debugname
== 0)
490 return (sysctl_rdstring(oldp
, oldlenp
, newp
, cdp
->debugname
));
491 case CTL_DEBUG_VALUE
:
492 return (sysctl_int(oldp
, oldlenp
, newp
, newlen
, cdp
->debugvar
));
501 * Validate parameters and get old / set new parameters
502 * for an integer-valued sysctl function.
505 sysctl_int(oldp
, oldlenp
, newp
, newlen
, valp
)
514 if (oldp
&& *oldlenp
< sizeof(int))
516 if (newp
&& newlen
!= sizeof(int))
518 *oldlenp
= sizeof(int);
520 error
= copyout(valp
, oldp
, sizeof(int));
521 if (error
== 0 && newp
)
522 error
= copyin(newp
, valp
, sizeof(int));
527 * As above, but read-only.
530 sysctl_rdint(oldp
, oldlenp
, newp
, val
)
538 if (oldp
&& *oldlenp
< sizeof(int))
542 *oldlenp
= sizeof(int);
544 error
= copyout((caddr_t
)&val
, oldp
, sizeof(int));
549 * Validate parameters and get old / set new parameters
550 * for an quad(64bit)-valued sysctl function.
553 sysctl_quad(oldp
, oldlenp
, newp
, newlen
, valp
)
562 if (oldp
&& *oldlenp
< sizeof(quad_t
))
564 if (newp
&& newlen
!= sizeof(quad_t
))
566 *oldlenp
= sizeof(quad_t
);
568 error
= copyout(valp
, oldp
, sizeof(quad_t
));
569 if (error
== 0 && newp
)
570 error
= copyin(newp
, valp
, sizeof(quad_t
));
575 * As above, but read-only.
578 sysctl_rdquad(oldp
, oldlenp
, newp
, val
)
586 if (oldp
&& *oldlenp
< sizeof(quad_t
))
590 *oldlenp
= sizeof(quad_t
);
592 error
= copyout((caddr_t
)&val
, oldp
, sizeof(quad_t
));
597 * Validate parameters and get old / set new parameters
598 * for a string-valued sysctl function.
601 sysctl_string(oldp
, oldlenp
, newp
, newlen
, str
, maxlen
)
611 len
= strlen(str
) + 1;
612 if (oldp
&& *oldlenp
< len
)
614 if (newp
&& newlen
>= maxlen
)
616 *oldlenp
= len
-1; /* deal with NULL strings correctly */
618 error
= copyout(str
, oldp
, len
);
620 if (error
== 0 && newp
) {
621 error
= copyin(newp
, str
, newlen
);
628 * As above, but read-only.
631 sysctl_rdstring(oldp
, oldlenp
, newp
, str
)
639 len
= strlen(str
) + 1;
640 if (oldp
&& *oldlenp
< len
)
646 error
= copyout(str
, oldp
, len
);
651 * Validate parameters and get old / set new parameters
652 * for a structure oriented sysctl function.
655 sysctl_struct(oldp
, oldlenp
, newp
, newlen
, sp
, len
)
665 if (oldp
&& *oldlenp
< len
)
667 if (newp
&& newlen
> len
)
671 error
= copyout(sp
, oldp
, len
);
673 if (error
== 0 && newp
)
674 error
= copyin(newp
, sp
, len
);
679 * Validate parameters and get old parameters
680 * for a structure oriented sysctl function.
683 sysctl_rdstruct(oldp
, oldlenp
, newp
, sp
, len
)
691 if (oldp
&& *oldlenp
< len
)
697 error
= copyout(sp
, oldp
, len
);
702 * Get file structures.
705 sysctl_file(where
, sizep
)
716 * overestimate by 10 files
718 *sizep
= sizeof(filehead
) + (nfiles
+ 10) * sizeof(struct file
);
723 * first copyout filehead
725 if (buflen
< sizeof(filehead
)) {
729 if (error
= copyout((caddr_t
)&filehead
, where
, sizeof(filehead
)))
731 buflen
-= sizeof(filehead
);
732 where
+= sizeof(filehead
);
735 * followed by an array of file structures
737 for (fp
= filehead
.lh_first
; fp
!= 0; fp
= fp
->f_list
.le_next
) {
738 if (buflen
< sizeof(struct file
)) {
739 *sizep
= where
- start
;
742 if (error
= copyout((caddr_t
)fp
, where
, sizeof (struct file
)))
744 buflen
-= sizeof(struct file
);
745 where
+= sizeof(struct file
);
747 *sizep
= where
- start
;
752 * try over estimating by 5 procs
754 #define KERN_PROCSLOP (5 * sizeof (struct kinfo_proc))
757 sysctl_doproc(name
, namelen
, where
, sizep
)
763 register struct proc
*p
;
764 register struct kinfo_proc
*dp
= (struct kinfo_proc
*)where
;
765 register int needed
= 0;
766 int buflen
= where
!= NULL
? *sizep
: 0;
768 struct kinfo_proc kproc
;
771 if (namelen
!= 2 && !(namelen
== 1 && name
[0] == KERN_PROC_ALL
))
773 p
= allproc
.lh_first
;
776 for (; p
!= 0; p
= p
->p_list
.le_next
) {
778 * Skip embryonic processes.
780 if (p
->p_stat
== SIDL
)
783 * TODO - make more efficient (see notes below).
789 /* could do this with just a lookup */
790 if (p
->p_pid
!= (pid_t
)name
[1])
795 /* could do this by traversing pgrp */
796 if (p
->p_pgrp
->pg_id
!= (pid_t
)name
[1])
801 if ( doingzomb
|| (p
->p_flag
& P_CONTROLT
) == 0 ||
802 p
->p_session
->s_ttyp
== NULL
||
803 p
->p_session
->s_ttyp
->t_dev
!= (dev_t
)name
[1])
808 if (doingzomb
|| (p
->p_ucred
->cr_uid
!= (uid_t
)name
[1]))
813 if ( doingzomb
|| (p
->p_cred
->p_ruid
!= (uid_t
)name
[1]))
817 if (buflen
>= sizeof(struct kinfo_proc
)) {
818 bzero(&kproc
, sizeof(struct kinfo_proc
));
819 fill_proc(p
, &kproc
, doingzomb
);
820 if (error
= copyout((caddr_t
)&kproc
, &dp
->kp_proc
,
821 sizeof(struct kinfo_proc
)))
824 buflen
-= sizeof(struct kinfo_proc
);
826 needed
+= sizeof(struct kinfo_proc
);
828 if (doingzomb
== 0) {
829 p
= zombproc
.lh_first
;
834 *sizep
= (caddr_t
)dp
- where
;
838 needed
+= KERN_PROCSLOP
;
845 fill_proc(p
,kp
, doingzomb
)
846 register struct proc
*p
;
847 register struct kinfo_proc
*kp
;
850 fill_externproc(p
, &kp
->kp_proc
);
852 fill_eproc(p
, &kp
->kp_eproc
);
855 * Fill in an eproc structure for the specified process.
859 register struct proc
*p
;
860 register struct eproc
*ep
;
862 register struct tty
*tp
;
865 * Skip zombie processes.
867 if (p
->p_stat
== SZOMB
)
871 ep
->e_sess
= p
->p_pgrp
->pg_session
;
872 ep
->e_pcred
= *p
->p_cred
;
873 ep
->e_ucred
= *p
->p_ucred
;
874 if (p
->p_stat
== SIDL
|| p
->p_stat
== SZOMB
) {
875 ep
->e_vm
.vm_tsize
= 0;
876 ep
->e_vm
.vm_dsize
= 0;
877 ep
->e_vm
.vm_ssize
= 0;
879 ep
->e_vm
.vm_rssize
= 0;
881 ep
->e_ppid
= p
->p_pptr
->p_pid
;
884 ep
->e_pgid
= p
->p_pgrp
->pg_id
;
885 ep
->e_jobc
= p
->p_pgrp
->pg_jobc
;
886 if ((p
->p_flag
& P_CONTROLT
) &&
887 (tp
= ep
->e_sess
->s_ttyp
)) {
888 ep
->e_tdev
= tp
->t_dev
;
889 ep
->e_tpgid
= tp
->t_pgrp
? tp
->t_pgrp
->pg_id
: NO_PID
;
890 ep
->e_tsess
= tp
->t_session
;
893 ep
->e_flag
= ep
->e_sess
->s_ttyvp
? EPROC_CTTY
: 0;
895 ep
->e_flag
|= EPROC_SLEADER
;
897 strncpy(ep
->e_wmesg
, p
->p_wmesg
, WMESGLEN
);
898 ep
->e_xsize
= ep
->e_xrssize
= 0;
899 ep
->e_xccount
= ep
->e_xswrss
= 0;
902 * Fill in an eproc structure for the specified process.
905 fill_externproc(p
, exp
)
906 register struct proc
*p
;
907 register struct extern_proc
*exp
;
909 exp
->p_forw
= exp
->p_back
= NULL
;
911 exp
->p_starttime
= p
->p_stats
->p_start
;
912 exp
->p_vmspace
= NULL
;
913 exp
->p_sigacts
= p
->p_sigacts
;
914 exp
->p_flag
= p
->p_flag
;
915 exp
->p_stat
= p
->p_stat
;
916 exp
->p_pid
= p
->p_pid
;
917 exp
->p_oppid
= p
->p_oppid
;
918 exp
->p_dupfd
= p
->p_dupfd
;
920 exp
->user_stack
= p
->user_stack
;
921 exp
->exit_thread
= p
->exit_thread
;
922 exp
->p_debugger
= p
->p_debugger
;
923 exp
->sigwait
= p
->sigwait
;
925 exp
->p_estcpu
= p
->p_estcpu
;
926 exp
->p_cpticks
= p
->p_cpticks
;
927 exp
->p_pctcpu
= p
->p_pctcpu
;
928 exp
->p_wchan
= p
->p_wchan
;
929 exp
->p_wmesg
= p
->p_wmesg
;
930 exp
->p_swtime
= p
->p_swtime
;
931 exp
->p_slptime
= p
->p_slptime
;
932 bcopy(&p
->p_realtimer
, &exp
->p_realtimer
,sizeof(struct itimerval
));
933 bcopy(&p
->p_rtime
, &exp
->p_rtime
,sizeof(struct timeval
));
934 exp
->p_uticks
= p
->p_uticks
;
935 exp
->p_sticks
= p
->p_sticks
;
936 exp
->p_iticks
= p
->p_iticks
;
937 exp
->p_traceflag
= p
->p_traceflag
;
938 exp
->p_tracep
= p
->p_tracep
;
939 exp
->p_siglist
= 0 ; /* No longer relevant */
940 exp
->p_textvp
= p
->p_textvp
;
942 exp
->p_sigmask
= 0 ; /* no longer avaialable */
943 exp
->p_sigignore
= p
->p_sigignore
;
944 exp
->p_sigcatch
= p
->p_sigcatch
;
945 exp
->p_priority
= p
->p_priority
;
946 exp
->p_usrpri
= p
->p_usrpri
;
947 exp
->p_nice
= p
->p_nice
;
948 bcopy(&p
->p_comm
, &exp
->p_comm
,MAXCOMLEN
);
949 exp
->p_comm
[MAXCOMLEN
] = '\0';
950 exp
->p_pgrp
= p
->p_pgrp
;
952 exp
->p_xstat
= p
->p_xstat
;
953 exp
->p_acflag
= p
->p_acflag
;
954 exp
->p_ru
= p
->p_ru
;
958 kdebug_ops(name
, namelen
, where
, sizep
, p
)
967 extern int kdbg_control(int *name
, u_int namelen
,
968 char * where
,size_t * sizep
);
970 if (ret
= suser(p
->p_ucred
, &p
->p_acflag
))
986 case KERN_KDSETRTCDEC
:
988 case KERN_KDGETENTROPY
:
989 ret
= kdbg_control(name
, namelen
, where
, sizep
);
999 pcsamples_ops(name
, namelen
, where
, sizep
, p
)
1007 extern int pcsamples_control(int *name
, u_int namelen
,
1008 char * where
,size_t * sizep
);
1010 if (ret
= suser(p
->p_ucred
, &p
->p_acflag
))
1014 case KERN_PCDISABLE
:
1018 case KERN_PCREADBUF
:
1022 ret
= pcsamples_control(name
, namelen
, where
, sizep
);
1032 * Returns the top N bytes of the user stack, with
1033 * everything below the first argument character
1034 * zeroed for security reasons.
1035 * Odd data structure is for compatibility.
1038 sysctl_procargs(name
, namelen
, where
, sizep
, cur_proc
)
1043 struct proc
*cur_proc
;
1045 register struct proc
*p
;
1046 register int needed
= 0;
1047 int buflen
= where
!= NULL
? *sizep
: 0;
1049 struct vm_map
*proc_map
;
1052 vm_offset_t arg_addr
;
1056 vm_offset_t copy_start
, copy_end
;
1057 vm_offset_t dealloc_start
; /* area to remove from kernel map */
1058 vm_offset_t dealloc_end
;
1064 if ((buflen
<= 0) || (buflen
> (PAGE_SIZE
<< 1))) {
1070 * Lookup process by pid
1081 * Copy the top N bytes of the stack.
1082 * On all machines we have so far, the stack grows
1085 * If the user expects no more than N bytes of
1086 * argument list, use that as a guess for the
1093 if ((p
->p_ucred
->cr_uid
!= cur_proc
->p_ucred
->cr_uid
)
1094 && suser(cur_proc
->p_ucred
, &cur_proc
->p_acflag
))
1096 arg_addr
= (vm_offset_t
)(p
->user_stack
- arg_size
);
1100 * Before we can block (any VM code), make another
1101 * reference to the map to keep it alive. We do
1102 * that by getting a reference on the task itself.
1109 * A regular task_reference call can block, causing the funnel
1110 * to be dropped and allowing the proc/task to get freed.
1111 * Instead, we issue a non-blocking attempt at the task reference,
1112 * and look up the proc/task all over again if that fails.
1114 if (!task_reference_try(task
)) {
1119 ret
= kmem_alloc(kernel_map
, ©_start
, round_page_32(arg_size
));
1120 if (ret
!= KERN_SUCCESS
) {
1121 task_deallocate(task
);
1125 proc_map
= get_task_map(task
);
1126 copy_end
= round_page_32(copy_start
+ arg_size
);
1128 if( vm_map_copyin(proc_map
, trunc_page(arg_addr
), round_page_32(arg_size
),
1129 FALSE
, &tmp
) != KERN_SUCCESS
) {
1130 task_deallocate(task
);
1131 kmem_free(kernel_map
, copy_start
,
1132 round_page_32(arg_size
));
1137 * Now that we've done the copyin from the process'
1138 * map, we can release the reference to it.
1140 task_deallocate(task
);
1142 if( vm_map_copy_overwrite(kernel_map
, copy_start
,
1143 tmp
, FALSE
) != KERN_SUCCESS
) {
1144 kmem_free(kernel_map
, copy_start
,
1145 round_page_32(arg_size
));
1149 data
= (caddr_t
) (copy_end
- arg_size
);
1150 ip
= (int *) copy_end
;
1154 * Now look down the stack for the bottom of the
1155 * argument list. Since this call is otherwise
1156 * unprotected, we can't let the nosy user see
1157 * anything else on the stack.
1159 * The arguments are pushed on the stack by
1163 * arg 0 (null-terminated)
1171 ip
-= 2; /*skip trailing 0 word and assume at least one
1172 argument. The last word of argN may be just
1173 the trailing 0, in which case we'd stop
1176 if (ip
== (int *)data
)
1179 * To account for saved path name and not having a null after that
1180 * Run the sweep again. If we have already sweeped entire range skip this
1182 if (ip
!= (int *)data
) {
1184 if (ip
== (int *)data
)
1188 bzero(data
, (unsigned) ((int)ip
- (int)data
));
1190 dealloc_start
= copy_start
;
1191 dealloc_end
= copy_end
;
1194 size
= MIN(size
, buflen
);
1195 error
= copyout(data
, where
, size
);
1197 if (dealloc_start
!= (vm_offset_t
) 0) {
1198 kmem_free(kernel_map
, dealloc_start
,
1199 dealloc_end
- dealloc_start
);