init_sysctl.c revision 1.90
1/*	$NetBSD: init_sysctl.c,v 1.90 2006/10/29 22:34:07 christos Exp $ */
2
3/*-
4 * Copyright (c) 2003 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Andrew Brown.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 *    must display the following acknowledgement:
20 *      This product includes software developed by the NetBSD
21 *      Foundation, Inc. and its contributors.
22 * 4. Neither the name of The NetBSD Foundation nor the names of its
23 *    contributors may be used to endorse or promote products derived
24 *    from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 */
38
39#include <sys/cdefs.h>
40__KERNEL_RCSID(0, "$NetBSD: init_sysctl.c,v 1.90 2006/10/29 22:34:07 christos Exp $");
41
42#include "opt_sysv.h"
43#include "opt_multiprocessor.h"
44#include "opt_posix.h"
45#include "opt_compat_netbsd32.h"
46#include "opt_ktrace.h"
47#include "veriexec.h"
48#include "pty.h"
49#include "rnd.h"
50
51#include <sys/types.h>
52#include <sys/param.h>
53#include <sys/sysctl.h>
54#include <sys/errno.h>
55#include <sys/systm.h>
56#include <sys/kernel.h>
57#include <sys/unistd.h>
58#include <sys/disklabel.h>
59#include <sys/rnd.h>
60#include <sys/vnode.h>
61#include <sys/mount.h>
62#include <sys/namei.h>
63#include <sys/msgbuf.h>
64#include <dev/cons.h>
65#include <sys/socketvar.h>
66#include <sys/file.h>
67#include <sys/filedesc.h>
68#include <sys/tty.h>
69#include <sys/malloc.h>
70#include <sys/resource.h>
71#include <sys/resourcevar.h>
72#include <sys/exec.h>
73#include <sys/conf.h>
74#include <sys/device.h>
75#if NVERIEXEC > 0
76#define	VERIEXEC_NEED_NODE
77#include <sys/verified_exec.h>
78#endif /* NVERIEXEC > 0 */
79#include <sys/stat.h>
80#include <sys/kauth.h>
81#ifdef KTRACE
82#include <sys/ktrace.h>
83#endif
84
85#if defined(SYSVMSG) || defined(SYSVSEM) || defined(SYSVSHM)
86#include <sys/ipc.h>
87#endif
88#ifdef SYSVMSG
89#include <sys/msg.h>
90#endif
91#ifdef SYSVSEM
92#include <sys/sem.h>
93#endif
94#ifdef SYSVSHM
95#include <sys/shm.h>
96#endif
97
98#ifdef COMPAT_NETBSD32
99#include <compat/netbsd32/netbsd32.h>
100#endif
101
102#include <machine/cpu.h>
103
104/* XXX this should not be here */
105int security_setidcore_dump;
106char security_setidcore_path[MAXPATHLEN] = "/var/crash/%n.core";
107uid_t security_setidcore_owner = 0;
108gid_t security_setidcore_group = 0;
109mode_t security_setidcore_mode = (S_IRUSR|S_IWUSR);
110
111/*
112 * try over estimating by 5 procs/lwps
113 */
114#define KERN_PROCSLOP	(5 * sizeof(struct kinfo_proc))
115#define KERN_LWPSLOP	(5 * sizeof(struct kinfo_lwp))
116
117#ifdef KTRACE
118int dcopyout(struct lwp *, const void *, void *, size_t);
119
120int
121dcopyout(l, kaddr, uaddr, len)
122	struct lwp *l;
123	const void *kaddr;
124	void *uaddr;
125	size_t len;
126{
127	int error;
128
129	error = copyout(kaddr, uaddr, len);
130	if (!error && KTRPOINT(l->l_proc, KTR_MIB)) {
131		struct iovec iov;
132
133		iov.iov_base = uaddr;
134		iov.iov_len = len;
135		ktrgenio(l, -1, UIO_READ, &iov, len, 0);
136	}
137	return error;
138}
139#else /* !KTRACE */
140#define dcopyout(l, kaddr, uaddr, len) copyout(kaddr, uaddr, len)
141#endif /* KTRACE */
142#ifndef MULTIPROCESSOR
143#define	sysctl_ncpus()	(1)
144#else /* MULTIPROCESSOR */
145#ifndef CPU_INFO_FOREACH
146#define CPU_INFO_ITERATOR int
147#define CPU_INFO_FOREACH(cii, ci) cii = 0, ci = curcpu(); ci != NULL; ci = NULL
148#endif
149static int
150sysctl_ncpus(void)
151{
152	struct cpu_info *ci;
153	CPU_INFO_ITERATOR cii;
154
155	int ncpus = 0;
156	for (CPU_INFO_FOREACH(cii, ci))
157		ncpus++;
158	return (ncpus);
159}
160#endif /* MULTIPROCESSOR */
161
162#ifdef DIAGNOSTIC
163static int sysctl_kern_trigger_panic(SYSCTLFN_PROTO);
164#endif
165static int sysctl_kern_maxvnodes(SYSCTLFN_PROTO);
166static int sysctl_kern_rtc_offset(SYSCTLFN_PROTO);
167static int sysctl_kern_maxproc(SYSCTLFN_PROTO);
168static int sysctl_kern_hostid(SYSCTLFN_PROTO);
169static int sysctl_setlen(SYSCTLFN_PROTO);
170static int sysctl_kern_clockrate(SYSCTLFN_PROTO);
171static int sysctl_kern_file(SYSCTLFN_PROTO);
172static int sysctl_kern_autonice(SYSCTLFN_PROTO);
173static int sysctl_msgbuf(SYSCTLFN_PROTO);
174static int sysctl_kern_defcorename(SYSCTLFN_PROTO);
175static int sysctl_kern_cptime(SYSCTLFN_PROTO);
176#if defined(SYSVMSG) || defined(SYSVSEM) || defined(SYSVSHM)
177static int sysctl_kern_sysvipc(SYSCTLFN_PROTO);
178#endif /* defined(SYSVMSG) || defined(SYSVSEM) || defined(SYSVSHM) */
179#if NPTY > 0
180static int sysctl_kern_maxptys(SYSCTLFN_PROTO);
181#endif /* NPTY > 0 */
182static int sysctl_kern_sbmax(SYSCTLFN_PROTO);
183static int sysctl_kern_urnd(SYSCTLFN_PROTO);
184static int sysctl_kern_lwp(SYSCTLFN_PROTO);
185static int sysctl_kern_forkfsleep(SYSCTLFN_PROTO);
186static int sysctl_kern_root_partition(SYSCTLFN_PROTO);
187static int sysctl_kern_drivers(SYSCTLFN_PROTO);
188static int sysctl_kern_file2(SYSCTLFN_PROTO);
189#if NVERIEXEC > 0
190static int sysctl_kern_veriexec(SYSCTLFN_PROTO);
191#endif /* NVERIEXEC > 0 */
192static int sysctl_security_setidcore(SYSCTLFN_PROTO);
193static int sysctl_security_setidcorename(SYSCTLFN_PROTO);
194static int sysctl_kern_cpid(SYSCTLFN_PROTO);
195static int sysctl_doeproc(SYSCTLFN_PROTO);
196static int sysctl_kern_proc_args(SYSCTLFN_PROTO);
197static int sysctl_hw_usermem(SYSCTLFN_PROTO);
198static int sysctl_hw_cnmagic(SYSCTLFN_PROTO);
199static int sysctl_hw_ncpu(SYSCTLFN_PROTO);
200
201static void fill_kproc2(struct proc *, struct kinfo_proc2 *);
202static void fill_lwp(struct lwp *l, struct kinfo_lwp *kl);
203static void fill_file(struct kinfo_file *, const struct file *, struct proc *,
204		      int);
205
206/*
207 * ********************************************************************
208 * section 1: setup routines
209 * ********************************************************************
210 * these functions are stuffed into a link set for sysctl setup
211 * functions.  they're never called or referenced from anywhere else.
212 * ********************************************************************
213 */
214
215/*
216 * sets up the base nodes...
217 */
218SYSCTL_SETUP(sysctl_root_setup, "sysctl base setup")
219{
220
221	sysctl_createv(clog, 0, NULL, NULL,
222		       CTLFLAG_PERMANENT,
223		       CTLTYPE_NODE, "kern",
224		       SYSCTL_DESCR("High kernel"),
225		       NULL, 0, NULL, 0,
226		       CTL_KERN, CTL_EOL);
227	sysctl_createv(clog, 0, NULL, NULL,
228		       CTLFLAG_PERMANENT,
229		       CTLTYPE_NODE, "vm",
230		       SYSCTL_DESCR("Virtual memory"),
231		       NULL, 0, NULL, 0,
232		       CTL_VM, CTL_EOL);
233	sysctl_createv(clog, 0, NULL, NULL,
234		       CTLFLAG_PERMANENT,
235		       CTLTYPE_NODE, "vfs",
236		       SYSCTL_DESCR("Filesystem"),
237		       NULL, 0, NULL, 0,
238		       CTL_VFS, CTL_EOL);
239	sysctl_createv(clog, 0, NULL, NULL,
240		       CTLFLAG_PERMANENT,
241		       CTLTYPE_NODE, "net",
242		       SYSCTL_DESCR("Networking"),
243		       NULL, 0, NULL, 0,
244		       CTL_NET, CTL_EOL);
245	sysctl_createv(clog, 0, NULL, NULL,
246		       CTLFLAG_PERMANENT,
247		       CTLTYPE_NODE, "debug",
248		       SYSCTL_DESCR("Debugging"),
249		       NULL, 0, NULL, 0,
250		       CTL_DEBUG, CTL_EOL);
251	sysctl_createv(clog, 0, NULL, NULL,
252		       CTLFLAG_PERMANENT,
253		       CTLTYPE_NODE, "hw",
254		       SYSCTL_DESCR("Generic CPU, I/O"),
255		       NULL, 0, NULL, 0,
256		       CTL_HW, CTL_EOL);
257	sysctl_createv(clog, 0, NULL, NULL,
258		       CTLFLAG_PERMANENT,
259		       CTLTYPE_NODE, "machdep",
260		       SYSCTL_DESCR("Machine dependent"),
261		       NULL, 0, NULL, 0,
262		       CTL_MACHDEP, CTL_EOL);
263	/*
264	 * this node is inserted so that the sysctl nodes in libc can
265	 * operate.
266	 */
267	sysctl_createv(clog, 0, NULL, NULL,
268		       CTLFLAG_PERMANENT,
269		       CTLTYPE_NODE, "user",
270		       SYSCTL_DESCR("User-level"),
271		       NULL, 0, NULL, 0,
272		       CTL_USER, CTL_EOL);
273	sysctl_createv(clog, 0, NULL, NULL,
274		       CTLFLAG_PERMANENT,
275		       CTLTYPE_NODE, "ddb",
276		       SYSCTL_DESCR("In-kernel debugger"),
277		       NULL, 0, NULL, 0,
278		       CTL_DDB, CTL_EOL);
279	sysctl_createv(clog, 0, NULL, NULL,
280		       CTLFLAG_PERMANENT,
281		       CTLTYPE_NODE, "proc",
282		       SYSCTL_DESCR("Per-process"),
283		       NULL, 0, NULL, 0,
284		       CTL_PROC, CTL_EOL);
285	sysctl_createv(clog, 0, NULL, NULL,
286		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
287		       CTLTYPE_NODE, "vendor",
288		       SYSCTL_DESCR("Vendor specific"),
289		       NULL, 0, NULL, 0,
290		       CTL_VENDOR, CTL_EOL);
291	sysctl_createv(clog, 0, NULL, NULL,
292		       CTLFLAG_PERMANENT,
293		       CTLTYPE_NODE, "emul",
294		       SYSCTL_DESCR("Emulation settings"),
295		       NULL, 0, NULL, 0,
296		       CTL_EMUL, CTL_EOL);
297	sysctl_createv(clog, 0, NULL, NULL,
298		       CTLFLAG_PERMANENT,
299		       CTLTYPE_NODE, "security",
300		       SYSCTL_DESCR("Security"),
301		       NULL, 0, NULL, 0,
302		       CTL_SECURITY, CTL_EOL);
303}
304
305/*
306 * this setup routine is a replacement for kern_sysctl()
307 */
308SYSCTL_SETUP(sysctl_kern_setup, "sysctl kern subtree setup")
309{
310	extern int kern_logsigexit;	/* defined in kern/kern_sig.c */
311	extern fixpt_t ccpu;		/* defined in kern/kern_synch.c */
312	extern int dumponpanic;		/* defined in kern/subr_prf.c */
313	const struct sysctlnode *rnode;
314
315	sysctl_createv(clog, 0, NULL, NULL,
316		       CTLFLAG_PERMANENT,
317		       CTLTYPE_NODE, "kern", NULL,
318		       NULL, 0, NULL, 0,
319		       CTL_KERN, CTL_EOL);
320
321	sysctl_createv(clog, 0, NULL, NULL,
322		       CTLFLAG_PERMANENT,
323		       CTLTYPE_STRING, "ostype",
324		       SYSCTL_DESCR("Operating system type"),
325		       NULL, 0, &ostype, 0,
326		       CTL_KERN, KERN_OSTYPE, CTL_EOL);
327	sysctl_createv(clog, 0, NULL, NULL,
328		       CTLFLAG_PERMANENT,
329		       CTLTYPE_STRING, "osrelease",
330		       SYSCTL_DESCR("Operating system release"),
331		       NULL, 0, &osrelease, 0,
332		       CTL_KERN, KERN_OSRELEASE, CTL_EOL);
333	sysctl_createv(clog, 0, NULL, NULL,
334		       CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
335		       CTLTYPE_INT, "osrevision",
336		       SYSCTL_DESCR("Operating system revision"),
337		       NULL, __NetBSD_Version__, NULL, 0,
338		       CTL_KERN, KERN_OSREV, CTL_EOL);
339	sysctl_createv(clog, 0, NULL, NULL,
340		       CTLFLAG_PERMANENT,
341		       CTLTYPE_STRING, "version",
342		       SYSCTL_DESCR("Kernel version"),
343		       NULL, 0, &version, 0,
344		       CTL_KERN, KERN_VERSION, CTL_EOL);
345	sysctl_createv(clog, 0, NULL, NULL,
346		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
347		       CTLTYPE_INT, "maxvnodes",
348		       SYSCTL_DESCR("Maximum number of vnodes"),
349		       sysctl_kern_maxvnodes, 0, NULL, 0,
350		       CTL_KERN, KERN_MAXVNODES, CTL_EOL);
351	sysctl_createv(clog, 0, NULL, NULL,
352		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
353		       CTLTYPE_INT, "maxproc",
354		       SYSCTL_DESCR("Maximum number of simultaneous processes"),
355		       sysctl_kern_maxproc, 0, NULL, 0,
356		       CTL_KERN, KERN_MAXPROC, CTL_EOL);
357	sysctl_createv(clog, 0, NULL, NULL,
358		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
359		       CTLTYPE_INT, "maxfiles",
360		       SYSCTL_DESCR("Maximum number of open files"),
361		       NULL, 0, &maxfiles, 0,
362		       CTL_KERN, KERN_MAXFILES, CTL_EOL);
363	sysctl_createv(clog, 0, NULL, NULL,
364		       CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
365		       CTLTYPE_INT, "argmax",
366		       SYSCTL_DESCR("Maximum number of bytes of arguments to "
367				    "execve(2)"),
368		       NULL, ARG_MAX, NULL, 0,
369		       CTL_KERN, KERN_ARGMAX, CTL_EOL);
370	sysctl_createv(clog, 0, NULL, NULL,
371		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
372		       CTLTYPE_STRING, "hostname",
373		       SYSCTL_DESCR("System hostname"),
374		       sysctl_setlen, 0, &hostname, MAXHOSTNAMELEN,
375		       CTL_KERN, KERN_HOSTNAME, CTL_EOL);
376	sysctl_createv(clog, 0, NULL, NULL,
377		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE|CTLFLAG_HEX,
378		       CTLTYPE_INT, "hostid",
379		       SYSCTL_DESCR("System host ID number"),
380		       sysctl_kern_hostid, 0, NULL, 0,
381		       CTL_KERN, KERN_HOSTID, CTL_EOL);
382	sysctl_createv(clog, 0, NULL, NULL,
383		       CTLFLAG_PERMANENT,
384		       CTLTYPE_STRUCT, "clockrate",
385		       SYSCTL_DESCR("Kernel clock rates"),
386		       sysctl_kern_clockrate, 0, NULL,
387		       sizeof(struct clockinfo),
388		       CTL_KERN, KERN_CLOCKRATE, CTL_EOL);
389	sysctl_createv(clog, 0, NULL, NULL,
390		       CTLFLAG_PERMANENT,
391		       CTLTYPE_INT, "hardclock_ticks",
392		       SYSCTL_DESCR("Number of hardclock ticks"),
393		       NULL, 0, &hardclock_ticks, sizeof(hardclock_ticks),
394		       CTL_KERN, KERN_HARDCLOCK_TICKS, CTL_EOL);
395	sysctl_createv(clog, 0, NULL, NULL,
396		       CTLFLAG_PERMANENT,
397		       CTLTYPE_STRUCT, "vnode",
398		       SYSCTL_DESCR("System vnode table"),
399		       sysctl_kern_vnode, 0, NULL, 0,
400		       CTL_KERN, KERN_VNODE, CTL_EOL);
401	sysctl_createv(clog, 0, NULL, NULL,
402		       CTLFLAG_PERMANENT,
403		       CTLTYPE_STRUCT, "file",
404		       SYSCTL_DESCR("System open file table"),
405		       sysctl_kern_file, 0, NULL, 0,
406		       CTL_KERN, KERN_FILE, CTL_EOL);
407#ifndef GPROF
408	sysctl_createv(clog, 0, NULL, NULL,
409		       CTLFLAG_PERMANENT,
410		       CTLTYPE_NODE, "profiling",
411		       SYSCTL_DESCR("Profiling information (not available)"),
412		       sysctl_notavail, 0, NULL, 0,
413		       CTL_KERN, KERN_PROF, CTL_EOL);
414#endif
415	sysctl_createv(clog, 0, NULL, NULL,
416		       CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
417		       CTLTYPE_INT, "posix1version",
418		       SYSCTL_DESCR("Version of ISO/IEC 9945 (POSIX 1003.1) "
419				    "with which the operating system attempts "
420				    "to comply"),
421		       NULL, _POSIX_VERSION, NULL, 0,
422		       CTL_KERN, KERN_POSIX1, CTL_EOL);
423	sysctl_createv(clog, 0, NULL, NULL,
424		       CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
425		       CTLTYPE_INT, "ngroups",
426		       SYSCTL_DESCR("Maximum number of supplemental groups"),
427		       NULL, NGROUPS_MAX, NULL, 0,
428		       CTL_KERN, KERN_NGROUPS, CTL_EOL);
429	sysctl_createv(clog, 0, NULL, NULL,
430		       CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
431		       CTLTYPE_INT, "job_control",
432		       SYSCTL_DESCR("Whether job control is available"),
433		       NULL, 1, NULL, 0,
434		       CTL_KERN, KERN_JOB_CONTROL, CTL_EOL);
435	sysctl_createv(clog, 0, NULL, NULL,
436		       CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
437		       CTLTYPE_INT, "saved_ids",
438		       SYSCTL_DESCR("Whether POSIX saved set-group/user ID is "
439				    "available"), NULL,
440#ifdef _POSIX_SAVED_IDS
441		       1,
442#else /* _POSIX_SAVED_IDS */
443		       0,
444#endif /* _POSIX_SAVED_IDS */
445		       NULL, 0, CTL_KERN, KERN_SAVED_IDS, CTL_EOL);
446	sysctl_createv(clog, 0, NULL, NULL,
447		       CTLFLAG_PERMANENT,
448		       CTLTYPE_STRUCT, "boottime",
449		       SYSCTL_DESCR("System boot time"),
450		       NULL, 0, &boottime, sizeof(boottime),
451		       CTL_KERN, KERN_BOOTTIME, CTL_EOL);
452	sysctl_createv(clog, 0, NULL, NULL,
453		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
454		       CTLTYPE_STRING, "domainname",
455		       SYSCTL_DESCR("YP domain name"),
456		       sysctl_setlen, 0, &domainname, MAXHOSTNAMELEN,
457		       CTL_KERN, KERN_DOMAINNAME, CTL_EOL);
458	sysctl_createv(clog, 0, NULL, NULL,
459		       CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
460		       CTLTYPE_INT, "maxpartitions",
461		       SYSCTL_DESCR("Maximum number of partitions allowed per "
462				    "disk"),
463		       NULL, MAXPARTITIONS, NULL, 0,
464		       CTL_KERN, KERN_MAXPARTITIONS, CTL_EOL);
465	sysctl_createv(clog, 0, NULL, NULL,
466		       CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
467		       CTLTYPE_INT, "rawpartition",
468		       SYSCTL_DESCR("Raw partition of a disk"),
469		       NULL, RAW_PART, NULL, 0,
470		       CTL_KERN, KERN_RAWPARTITION, CTL_EOL);
471	sysctl_createv(clog, 0, NULL, NULL,
472		       CTLFLAG_PERMANENT,
473		       CTLTYPE_STRUCT, "timex", NULL,
474		       sysctl_notavail, 0, NULL, 0,
475		       CTL_KERN, KERN_TIMEX, CTL_EOL);
476	sysctl_createv(clog, 0, NULL, NULL,
477		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
478		       CTLTYPE_INT, "autonicetime",
479		       SYSCTL_DESCR("CPU clock seconds before non-root "
480				    "process priority is lowered"),
481		       sysctl_kern_autonice, 0, &autonicetime, 0,
482		       CTL_KERN, KERN_AUTONICETIME, CTL_EOL);
483	sysctl_createv(clog, 0, NULL, NULL,
484		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
485		       CTLTYPE_INT, "autoniceval",
486		       SYSCTL_DESCR("Automatic reniced non-root process "
487				    "priority"),
488		       sysctl_kern_autonice, 0, &autoniceval, 0,
489		       CTL_KERN, KERN_AUTONICEVAL, CTL_EOL);
490	sysctl_createv(clog, 0, NULL, NULL,
491		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
492		       CTLTYPE_INT, "rtc_offset",
493		       SYSCTL_DESCR("Offset of real time clock from UTC in "
494				    "minutes"),
495		       sysctl_kern_rtc_offset, 0, &rtc_offset, 0,
496		       CTL_KERN, KERN_RTC_OFFSET, CTL_EOL);
497	sysctl_createv(clog, 0, NULL, NULL,
498		       CTLFLAG_PERMANENT,
499		       CTLTYPE_STRING, "root_device",
500		       SYSCTL_DESCR("Name of the root device"),
501		       sysctl_root_device, 0, NULL, 0,
502		       CTL_KERN, KERN_ROOT_DEVICE, CTL_EOL);
503	sysctl_createv(clog, 0, NULL, NULL,
504		       CTLFLAG_PERMANENT,
505		       CTLTYPE_INT, "msgbufsize",
506		       SYSCTL_DESCR("Size of the kernel message buffer"),
507		       sysctl_msgbuf, 0, NULL, 0,
508		       CTL_KERN, KERN_MSGBUFSIZE, CTL_EOL);
509	sysctl_createv(clog, 0, NULL, NULL,
510		       CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
511		       CTLTYPE_INT, "fsync",
512		       SYSCTL_DESCR("Whether the POSIX 1003.1b File "
513				    "Synchronization Option is available on "
514				    "this system"),
515		       NULL, 1, NULL, 0,
516		       CTL_KERN, KERN_FSYNC, CTL_EOL);
517	sysctl_createv(clog, 0, NULL, NULL,
518		       CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
519		       CTLTYPE_INT, "sysvmsg",
520		       SYSCTL_DESCR("System V style message support available"),
521		       NULL,
522#ifdef SYSVMSG
523		       1,
524#else /* SYSVMSG */
525		       0,
526#endif /* SYSVMSG */
527		       NULL, 0, CTL_KERN, KERN_SYSVMSG, CTL_EOL);
528	sysctl_createv(clog, 0, NULL, NULL,
529		       CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
530		       CTLTYPE_INT, "sysvsem",
531		       SYSCTL_DESCR("System V style semaphore support "
532				    "available"), NULL,
533#ifdef SYSVSEM
534		       1,
535#else /* SYSVSEM */
536		       0,
537#endif /* SYSVSEM */
538		       NULL, 0, CTL_KERN, KERN_SYSVSEM, CTL_EOL);
539	sysctl_createv(clog, 0, NULL, NULL,
540		       CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
541		       CTLTYPE_INT, "sysvshm",
542		       SYSCTL_DESCR("System V style shared memory support "
543				    "available"), NULL,
544#ifdef SYSVSHM
545		       1,
546#else /* SYSVSHM */
547		       0,
548#endif /* SYSVSHM */
549		       NULL, 0, CTL_KERN, KERN_SYSVSHM, CTL_EOL);
550	sysctl_createv(clog, 0, NULL, NULL,
551		       CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
552		       CTLTYPE_INT, "synchronized_io",
553		       SYSCTL_DESCR("Whether the POSIX 1003.1b Synchronized "
554				    "I/O Option is available on this system"),
555		       NULL, 1, NULL, 0,
556		       CTL_KERN, KERN_SYNCHRONIZED_IO, CTL_EOL);
557	sysctl_createv(clog, 0, NULL, NULL,
558		       CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
559		       CTLTYPE_INT, "iov_max",
560		       SYSCTL_DESCR("Maximum number of iovec structures per "
561				    "process"),
562		       NULL, IOV_MAX, NULL, 0,
563		       CTL_KERN, KERN_IOV_MAX, CTL_EOL);
564	sysctl_createv(clog, 0, NULL, NULL,
565		       CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
566		       CTLTYPE_INT, "mapped_files",
567		       SYSCTL_DESCR("Whether the POSIX 1003.1b Memory Mapped "
568				    "Files Option is available on this system"),
569		       NULL, 1, NULL, 0,
570		       CTL_KERN, KERN_MAPPED_FILES, CTL_EOL);
571	sysctl_createv(clog, 0, NULL, NULL,
572		       CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
573		       CTLTYPE_INT, "memlock",
574		       SYSCTL_DESCR("Whether the POSIX 1003.1b Process Memory "
575				    "Locking Option is available on this "
576				    "system"),
577		       NULL, 1, NULL, 0,
578		       CTL_KERN, KERN_MEMLOCK, CTL_EOL);
579	sysctl_createv(clog, 0, NULL, NULL,
580		       CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
581		       CTLTYPE_INT, "memlock_range",
582		       SYSCTL_DESCR("Whether the POSIX 1003.1b Range Memory "
583				    "Locking Option is available on this "
584				    "system"),
585		       NULL, 1, NULL, 0,
586		       CTL_KERN, KERN_MEMLOCK_RANGE, CTL_EOL);
587	sysctl_createv(clog, 0, NULL, NULL,
588		       CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
589		       CTLTYPE_INT, "memory_protection",
590		       SYSCTL_DESCR("Whether the POSIX 1003.1b Memory "
591				    "Protection Option is available on this "
592				    "system"),
593		       NULL, 1, NULL, 0,
594		       CTL_KERN, KERN_MEMORY_PROTECTION, CTL_EOL);
595	sysctl_createv(clog, 0, NULL, NULL,
596		       CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
597		       CTLTYPE_INT, "login_name_max",
598		       SYSCTL_DESCR("Maximum login name length"),
599		       NULL, LOGIN_NAME_MAX, NULL, 0,
600		       CTL_KERN, KERN_LOGIN_NAME_MAX, CTL_EOL);
601	sysctl_createv(clog, 0, NULL, NULL,
602		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
603		       CTLTYPE_STRING, "defcorename",
604		       SYSCTL_DESCR("Default core file name"),
605		       sysctl_kern_defcorename, 0, defcorename, MAXPATHLEN,
606		       CTL_KERN, KERN_DEFCORENAME, CTL_EOL);
607	sysctl_createv(clog, 0, NULL, NULL,
608		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
609		       CTLTYPE_INT, "logsigexit",
610		       SYSCTL_DESCR("Log process exit when caused by signals"),
611		       NULL, 0, &kern_logsigexit, 0,
612		       CTL_KERN, KERN_LOGSIGEXIT, CTL_EOL);
613	sysctl_createv(clog, 0, NULL, NULL,
614		       CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
615		       CTLTYPE_INT, "fscale",
616		       SYSCTL_DESCR("Kernel fixed-point scale factor"),
617		       NULL, FSCALE, NULL, 0,
618		       CTL_KERN, KERN_FSCALE, CTL_EOL);
619	sysctl_createv(clog, 0, NULL, NULL,
620		       CTLFLAG_PERMANENT,
621		       CTLTYPE_INT, "ccpu",
622		       SYSCTL_DESCR("Scheduler exponential decay value"),
623		       NULL, 0, &ccpu, 0,
624		       CTL_KERN, KERN_CCPU, CTL_EOL);
625	sysctl_createv(clog, 0, NULL, NULL,
626		       CTLFLAG_PERMANENT,
627		       CTLTYPE_STRUCT, "cp_time",
628		       SYSCTL_DESCR("Clock ticks spent in different CPU states"),
629		       sysctl_kern_cptime, 0, NULL, 0,
630		       CTL_KERN, KERN_CP_TIME, CTL_EOL);
631#if defined(SYSVMSG) || defined(SYSVSEM) || defined(SYSVSHM)
632	sysctl_createv(clog, 0, NULL, NULL,
633		       CTLFLAG_PERMANENT,
634		       CTLTYPE_STRUCT, "sysvipc_info",
635		       SYSCTL_DESCR("System V style IPC information"),
636		       sysctl_kern_sysvipc, 0, NULL, 0,
637		       CTL_KERN, KERN_SYSVIPC_INFO, CTL_EOL);
638#endif /* SYSVMSG || SYSVSEM || SYSVSHM */
639	sysctl_createv(clog, 0, NULL, NULL,
640		       CTLFLAG_PERMANENT,
641		       CTLTYPE_INT, "msgbuf",
642		       SYSCTL_DESCR("Kernel message buffer"),
643		       sysctl_msgbuf, 0, NULL, 0,
644		       CTL_KERN, KERN_MSGBUF, CTL_EOL);
645	sysctl_createv(clog, 0, NULL, NULL,
646		       CTLFLAG_PERMANENT,
647		       CTLTYPE_STRUCT, "consdev",
648		       SYSCTL_DESCR("Console device"),
649		       sysctl_consdev, 0, NULL, sizeof(dev_t),
650		       CTL_KERN, KERN_CONSDEV, CTL_EOL);
651#if NPTY > 0
652	sysctl_createv(clog, 0, NULL, NULL,
653		       CTLFLAG_PERMANENT,
654		       CTLTYPE_INT, "maxptys",
655		       SYSCTL_DESCR("Maximum number of pseudo-ttys"),
656		       sysctl_kern_maxptys, 0, NULL, 0,
657		       CTL_KERN, KERN_MAXPTYS, CTL_EOL);
658#endif /* NPTY > 0 */
659	sysctl_createv(clog, 0, NULL, NULL,
660		       CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
661		       CTLTYPE_INT, "maxphys",
662		       SYSCTL_DESCR("Maximum raw I/O transfer size"),
663		       NULL, MAXPHYS, NULL, 0,
664		       CTL_KERN, KERN_MAXPHYS, CTL_EOL);
665	sysctl_createv(clog, 0, NULL, NULL,
666		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
667		       CTLTYPE_INT, "sbmax",
668		       SYSCTL_DESCR("Maximum socket buffer size"),
669		       sysctl_kern_sbmax, 0, NULL, 0,
670		       CTL_KERN, KERN_SBMAX, CTL_EOL);
671	sysctl_createv(clog, 0, NULL, NULL,
672		       CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
673		       CTLTYPE_INT, "monotonic_clock",
674		       SYSCTL_DESCR("Implementation version of the POSIX "
675				    "1003.1b Monotonic Clock Option"),
676		       /* XXX _POSIX_VERSION */
677		       NULL, _POSIX_MONOTONIC_CLOCK, NULL, 0,
678		       CTL_KERN, KERN_MONOTONIC_CLOCK, CTL_EOL);
679	sysctl_createv(clog, 0, NULL, NULL,
680		       CTLFLAG_PERMANENT,
681		       CTLTYPE_INT, "urandom",
682		       SYSCTL_DESCR("Random integer value"),
683		       sysctl_kern_urnd, 0, NULL, 0,
684		       CTL_KERN, KERN_URND, CTL_EOL);
685	sysctl_createv(clog, 0, NULL, NULL,
686		       CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
687		       CTLTYPE_INT, "labelsector",
688		       SYSCTL_DESCR("Sector number containing the disklabel"),
689		       NULL, LABELSECTOR, NULL, 0,
690		       CTL_KERN, KERN_LABELSECTOR, CTL_EOL);
691	sysctl_createv(clog, 0, NULL, NULL,
692		       CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
693		       CTLTYPE_INT, "labeloffset",
694		       SYSCTL_DESCR("Offset of the disklabel within the "
695				    "sector"),
696		       NULL, LABELOFFSET, NULL, 0,
697		       CTL_KERN, KERN_LABELOFFSET, CTL_EOL);
698	sysctl_createv(clog, 0, NULL, NULL,
699		       CTLFLAG_PERMANENT,
700		       CTLTYPE_NODE, "lwp",
701		       SYSCTL_DESCR("System-wide LWP information"),
702		       sysctl_kern_lwp, 0, NULL, 0,
703		       CTL_KERN, KERN_LWP, CTL_EOL);
704	sysctl_createv(clog, 0, NULL, NULL,
705		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
706		       CTLTYPE_INT, "forkfsleep",
707		       SYSCTL_DESCR("Milliseconds to sleep on fork failure due "
708				    "to process limits"),
709		       sysctl_kern_forkfsleep, 0, NULL, 0,
710		       CTL_KERN, KERN_FORKFSLEEP, CTL_EOL);
711	sysctl_createv(clog, 0, NULL, NULL,
712		       CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
713		       CTLTYPE_INT, "posix_threads",
714		       SYSCTL_DESCR("Version of IEEE Std 1003.1 and its "
715				    "Threads option to which the system "
716				    "attempts to conform"),
717		       /* XXX _POSIX_VERSION */
718		       NULL, _POSIX_THREADS, NULL, 0,
719		       CTL_KERN, KERN_POSIX_THREADS, CTL_EOL);
720	sysctl_createv(clog, 0, NULL, NULL,
721		       CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
722		       CTLTYPE_INT, "posix_semaphores",
723		       SYSCTL_DESCR("Version of IEEE Std 1003.1 and its "
724				    "Semaphores option to which the system "
725				    "attempts to conform"), NULL,
726#ifdef P1003_1B_SEMAPHORE
727		       200112,
728#else /* P1003_1B_SEMAPHORE */
729		       0,
730#endif /* P1003_1B_SEMAPHORE */
731		       NULL, 0, CTL_KERN, KERN_POSIX_SEMAPHORES, CTL_EOL);
732	sysctl_createv(clog, 0, NULL, NULL,
733		       CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
734		       CTLTYPE_INT, "posix_barriers",
735		       SYSCTL_DESCR("Version of IEEE Std 1003.1 and its "
736				    "Barriers option to which the system "
737				    "attempts to conform"),
738		       /* XXX _POSIX_VERSION */
739		       NULL, _POSIX_BARRIERS, NULL, 0,
740		       CTL_KERN, KERN_POSIX_BARRIERS, CTL_EOL);
741	sysctl_createv(clog, 0, NULL, NULL,
742		       CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
743		       CTLTYPE_INT, "posix_timers",
744		       SYSCTL_DESCR("Version of IEEE Std 1003.1 and its "
745				    "Timers option to which the system "
746				    "attempts to conform"),
747		       /* XXX _POSIX_VERSION */
748		       NULL, _POSIX_TIMERS, NULL, 0,
749		       CTL_KERN, KERN_POSIX_TIMERS, CTL_EOL);
750	sysctl_createv(clog, 0, NULL, NULL,
751		       CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
752		       CTLTYPE_INT, "posix_spin_locks",
753		       SYSCTL_DESCR("Version of IEEE Std 1003.1 and its Spin "
754				    "Locks option to which the system attempts "
755				    "to conform"),
756		       /* XXX _POSIX_VERSION */
757		       NULL, _POSIX_SPIN_LOCKS, NULL, 0,
758		       CTL_KERN, KERN_POSIX_SPIN_LOCKS, CTL_EOL);
759	sysctl_createv(clog, 0, NULL, NULL,
760		       CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
761		       CTLTYPE_INT, "posix_reader_writer_locks",
762		       SYSCTL_DESCR("Version of IEEE Std 1003.1 and its "
763				    "Read-Write Locks option to which the "
764				    "system attempts to conform"),
765		       /* XXX _POSIX_VERSION */
766		       NULL, _POSIX_READER_WRITER_LOCKS, NULL, 0,
767		       CTL_KERN, KERN_POSIX_READER_WRITER_LOCKS, CTL_EOL);
768	sysctl_createv(clog, 0, NULL, NULL,
769		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
770		       CTLTYPE_INT, "dump_on_panic",
771		       SYSCTL_DESCR("Perform a crash dump on system panic"),
772		       NULL, 0, &dumponpanic, 0,
773		       CTL_KERN, KERN_DUMP_ON_PANIC, CTL_EOL);
774#ifdef DIAGNOSTIC
775	sysctl_createv(clog, 0, NULL, NULL,
776		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
777		       CTLTYPE_INT, "panic_now",
778		       SYSCTL_DESCR("Trigger a panic"),
779		       sysctl_kern_trigger_panic, 0, NULL, 0,
780		       CTL_KERN, CTL_CREATE, CTL_EOL);
781#endif
782	sysctl_createv(clog, 0, NULL, NULL,
783		       CTLFLAG_PERMANENT,
784		       CTLTYPE_INT, "root_partition",
785		       SYSCTL_DESCR("Root partition on the root device"),
786		       sysctl_kern_root_partition, 0, NULL, 0,
787		       CTL_KERN, KERN_ROOT_PARTITION, CTL_EOL);
788	sysctl_createv(clog, 0, NULL, NULL,
789		       CTLFLAG_PERMANENT,
790		       CTLTYPE_STRUCT, "drivers",
791		       SYSCTL_DESCR("List of all drivers with block and "
792				    "character device numbers"),
793		       sysctl_kern_drivers, 0, NULL, 0,
794		       CTL_KERN, KERN_DRIVERS, CTL_EOL);
795	sysctl_createv(clog, 0, NULL, NULL,
796		       CTLFLAG_PERMANENT,
797		       CTLTYPE_STRUCT, "file2",
798		       SYSCTL_DESCR("System open file table"),
799		       sysctl_kern_file2, 0, NULL, 0,
800		       CTL_KERN, KERN_FILE2, CTL_EOL);
801#if NVERIEXEC > 0
802	sysctl_createv(clog, 0, NULL, NULL,
803		       CTLFLAG_PERMANENT,
804		       CTLTYPE_NODE, "veriexec",
805		       SYSCTL_DESCR("Verified Exec"),
806		       NULL, 0, NULL, 0,
807		       CTL_KERN, KERN_VERIEXEC, CTL_EOL);
808	sysctl_createv(clog, 0, NULL, NULL,
809		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
810		       CTLTYPE_INT, "verbose",
811		       SYSCTL_DESCR("Verified Exec verbose level"),
812		       NULL, 0, &veriexec_verbose, 0,
813		       CTL_KERN, KERN_VERIEXEC, VERIEXEC_VERBOSE,
814		       CTL_EOL);
815	sysctl_createv(clog, 0, NULL, NULL,
816		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
817		       CTLTYPE_INT, "strict",
818		       SYSCTL_DESCR("Verified Exec strict level"),
819		       sysctl_kern_veriexec, 0, NULL, 0,
820		       CTL_KERN, KERN_VERIEXEC, VERIEXEC_STRICT, CTL_EOL);
821	sysctl_createv(clog, 0, NULL, NULL,
822		       CTLFLAG_PERMANENT,
823		       CTLTYPE_STRING, "algorithms",
824		       SYSCTL_DESCR("Verified Exec supported hashing "
825				    "algorithms"),
826		       sysctl_kern_veriexec, 0, NULL, 0,
827		       CTL_KERN, KERN_VERIEXEC, VERIEXEC_ALGORITHMS, CTL_EOL);
828	sysctl_createv(clog, 0, NULL, &veriexec_count_node,
829		       CTLFLAG_PERMANENT,
830		       CTLTYPE_NODE, "count",
831		       SYSCTL_DESCR("Number of fingerprints on device(s)"),
832		       NULL, 0, NULL, 0,
833		       CTL_KERN, KERN_VERIEXEC, VERIEXEC_COUNT, CTL_EOL);
834#endif /* NVERIEXEC > 0 */
835	sysctl_createv(clog, 0, NULL, NULL,
836		       CTLFLAG_PERMANENT,
837		       CTLTYPE_STRUCT, "cp_id",
838		       SYSCTL_DESCR("Mapping of CPU number to CPU id"),
839		       sysctl_kern_cpid, 0, NULL, 0,
840		       CTL_KERN, KERN_CP_ID, CTL_EOL);
841
842	sysctl_createv(clog, 0, NULL, &rnode,
843		       CTLFLAG_PERMANENT,
844		       CTLTYPE_NODE, "coredump",
845		       SYSCTL_DESCR("Coredump settings."),
846		       NULL, 0, NULL, 0,
847		       CTL_KERN, CTL_CREATE, CTL_EOL);
848	sysctl_createv(clog, 0, &rnode, &rnode,
849		       CTLFLAG_PERMANENT,
850		       CTLTYPE_NODE, "setid",
851		       SYSCTL_DESCR("Set-id processes' coredump settings."),
852		       NULL, 0, NULL, 0,
853		       CTL_CREATE, CTL_EOL);
854	sysctl_createv(clog, 0, &rnode, NULL,
855		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
856		       CTLTYPE_INT, "dump",
857		       SYSCTL_DESCR("Allow set-id processes to dump core."),
858		       sysctl_security_setidcore, 0, &security_setidcore_dump,
859		       sizeof(security_setidcore_dump),
860		       CTL_CREATE, CTL_EOL);
861	sysctl_createv(clog, 0, &rnode, NULL,
862		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
863		       CTLTYPE_STRING, "path",
864		       SYSCTL_DESCR("Path pattern for set-id coredumps."),
865		       sysctl_security_setidcorename, 0,
866		       &security_setidcore_path,
867		       sizeof(security_setidcore_path),
868		       CTL_CREATE, CTL_EOL);
869	sysctl_createv(clog, 0, &rnode, NULL,
870		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
871		       CTLTYPE_INT, "owner",
872		       SYSCTL_DESCR("Owner id for set-id processes' cores."),
873		       sysctl_security_setidcore, 0, &security_setidcore_owner,
874		       0,
875		       CTL_CREATE, CTL_EOL);
876	sysctl_createv(clog, 0, &rnode, NULL,
877		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
878		       CTLTYPE_INT, "group",
879		       SYSCTL_DESCR("Group id for set-id processes' cores."),
880		       sysctl_security_setidcore, 0, &security_setidcore_group,
881		       0,
882		       CTL_CREATE, CTL_EOL);
883	sysctl_createv(clog, 0, &rnode, NULL,
884		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
885		       CTLTYPE_INT, "mode",
886		       SYSCTL_DESCR("Mode for set-id processes' cores."),
887		       sysctl_security_setidcore, 0, &security_setidcore_mode,
888		       0,
889		       CTL_CREATE, CTL_EOL);
890}
891
892SYSCTL_SETUP(sysctl_kern_proc_setup,
893	     "sysctl kern.proc/proc2/proc_args subtree setup")
894{
895
896	sysctl_createv(clog, 0, NULL, NULL,
897		       CTLFLAG_PERMANENT,
898		       CTLTYPE_NODE, "kern", NULL,
899		       NULL, 0, NULL, 0,
900		       CTL_KERN, CTL_EOL);
901
902	sysctl_createv(clog, 0, NULL, NULL,
903		       CTLFLAG_PERMANENT,
904		       CTLTYPE_NODE, "proc",
905		       SYSCTL_DESCR("System-wide process information"),
906		       sysctl_doeproc, 0, NULL, 0,
907		       CTL_KERN, KERN_PROC, CTL_EOL);
908	sysctl_createv(clog, 0, NULL, NULL,
909		       CTLFLAG_PERMANENT,
910		       CTLTYPE_NODE, "proc2",
911		       SYSCTL_DESCR("Machine-independent process information"),
912		       sysctl_doeproc, 0, NULL, 0,
913		       CTL_KERN, KERN_PROC2, CTL_EOL);
914	sysctl_createv(clog, 0, NULL, NULL,
915		       CTLFLAG_PERMANENT,
916		       CTLTYPE_NODE, "proc_args",
917		       SYSCTL_DESCR("Process argument information"),
918		       sysctl_kern_proc_args, 0, NULL, 0,
919		       CTL_KERN, KERN_PROC_ARGS, CTL_EOL);
920
921	/*
922	  "nodes" under these:
923
924	  KERN_PROC_ALL
925	  KERN_PROC_PID pid
926	  KERN_PROC_PGRP pgrp
927	  KERN_PROC_SESSION sess
928	  KERN_PROC_TTY tty
929	  KERN_PROC_UID uid
930	  KERN_PROC_RUID uid
931	  KERN_PROC_GID gid
932	  KERN_PROC_RGID gid
933
934	  all in all, probably not worth the effort...
935	*/
936}
937
938SYSCTL_SETUP(sysctl_hw_setup, "sysctl hw subtree setup")
939{
940	u_int u;
941	u_quad_t q;
942
943	sysctl_createv(clog, 0, NULL, NULL,
944		       CTLFLAG_PERMANENT,
945		       CTLTYPE_NODE, "hw", NULL,
946		       NULL, 0, NULL, 0,
947		       CTL_HW, CTL_EOL);
948
949	sysctl_createv(clog, 0, NULL, NULL,
950		       CTLFLAG_PERMANENT,
951		       CTLTYPE_STRING, "machine",
952		       SYSCTL_DESCR("Machine class"),
953		       NULL, 0, machine, 0,
954		       CTL_HW, HW_MACHINE, CTL_EOL);
955	sysctl_createv(clog, 0, NULL, NULL,
956		       CTLFLAG_PERMANENT,
957		       CTLTYPE_STRING, "model",
958		       SYSCTL_DESCR("Machine model"),
959		       NULL, 0, cpu_model, 0,
960		       CTL_HW, HW_MODEL, CTL_EOL);
961	sysctl_createv(clog, 0, NULL, NULL,
962		       CTLFLAG_PERMANENT,
963		       CTLTYPE_INT, "ncpu",
964		       SYSCTL_DESCR("Number of active CPUs"),
965		       sysctl_hw_ncpu, 0, NULL, 0,
966		       CTL_HW, HW_NCPU, CTL_EOL);
967	sysctl_createv(clog, 0, NULL, NULL,
968		       CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
969		       CTLTYPE_INT, "byteorder",
970		       SYSCTL_DESCR("System byte order"),
971		       NULL, BYTE_ORDER, NULL, 0,
972		       CTL_HW, HW_BYTEORDER, CTL_EOL);
973	u = ((u_int)physmem > (UINT_MAX / PAGE_SIZE)) ?
974		UINT_MAX : physmem * PAGE_SIZE;
975	sysctl_createv(clog, 0, NULL, NULL,
976		       CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
977		       CTLTYPE_INT, "physmem",
978		       SYSCTL_DESCR("Bytes of physical memory"),
979		       NULL, u, NULL, 0,
980		       CTL_HW, HW_PHYSMEM, CTL_EOL);
981	sysctl_createv(clog, 0, NULL, NULL,
982		       CTLFLAG_PERMANENT,
983		       CTLTYPE_INT, "usermem",
984		       SYSCTL_DESCR("Bytes of non-kernel memory"),
985		       sysctl_hw_usermem, 0, NULL, 0,
986		       CTL_HW, HW_USERMEM, CTL_EOL);
987	sysctl_createv(clog, 0, NULL, NULL,
988		       CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
989		       CTLTYPE_INT, "pagesize",
990		       SYSCTL_DESCR("Software page size"),
991		       NULL, PAGE_SIZE, NULL, 0,
992		       CTL_HW, HW_PAGESIZE, CTL_EOL);
993	sysctl_createv(clog, 0, NULL, NULL,
994		       CTLFLAG_PERMANENT,
995		       CTLTYPE_STRING, "machine_arch",
996		       SYSCTL_DESCR("Machine CPU class"),
997		       NULL, 0, machine_arch, 0,
998		       CTL_HW, HW_MACHINE_ARCH, CTL_EOL);
999	sysctl_createv(clog, 0, NULL, NULL,
1000		       CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
1001		       CTLTYPE_INT, "alignbytes",
1002		       SYSCTL_DESCR("Alignment constraint for all possible "
1003				    "data types"),
1004		       NULL, ALIGNBYTES, NULL, 0,
1005		       CTL_HW, HW_ALIGNBYTES, CTL_EOL);
1006	sysctl_createv(clog, 0, NULL, NULL,
1007		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE|CTLFLAG_HEX,
1008		       CTLTYPE_STRING, "cnmagic",
1009		       SYSCTL_DESCR("Console magic key sequence"),
1010		       sysctl_hw_cnmagic, 0, NULL, CNS_LEN,
1011		       CTL_HW, HW_CNMAGIC, CTL_EOL);
1012	q = (u_quad_t)physmem * PAGE_SIZE;
1013	sysctl_createv(clog, 0, NULL, NULL,
1014		       CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
1015		       CTLTYPE_QUAD, "physmem64",
1016		       SYSCTL_DESCR("Bytes of physical memory"),
1017		       NULL, q, NULL, 0,
1018		       CTL_HW, HW_PHYSMEM64, CTL_EOL);
1019	sysctl_createv(clog, 0, NULL, NULL,
1020		       CTLFLAG_PERMANENT,
1021		       CTLTYPE_QUAD, "usermem64",
1022		       SYSCTL_DESCR("Bytes of non-kernel memory"),
1023		       sysctl_hw_usermem, 0, NULL, 0,
1024		       CTL_HW, HW_USERMEM64, CTL_EOL);
1025}
1026
1027#ifdef DEBUG
1028/*
1029 * Debugging related system variables.
1030 */
1031struct ctldebug /* debug0, */ /* debug1, */ debug2, debug3, debug4;
1032struct ctldebug debug5, debug6, debug7, debug8, debug9;
1033struct ctldebug debug10, debug11, debug12, debug13, debug14;
1034struct ctldebug debug15, debug16, debug17, debug18, debug19;
1035static struct ctldebug *debugvars[CTL_DEBUG_MAXID] = {
1036	&debug0, &debug1, &debug2, &debug3, &debug4,
1037	&debug5, &debug6, &debug7, &debug8, &debug9,
1038	&debug10, &debug11, &debug12, &debug13, &debug14,
1039	&debug15, &debug16, &debug17, &debug18, &debug19,
1040};
1041
1042/*
1043 * this setup routine is a replacement for debug_sysctl()
1044 *
1045 * note that it creates several nodes per defined debug variable
1046 */
1047SYSCTL_SETUP(sysctl_debug_setup, "sysctl debug subtree setup")
1048{
1049	struct ctldebug *cdp;
1050	char nodename[20];
1051	int i;
1052
1053	/*
1054	 * two ways here:
1055	 *
1056	 * the "old" way (debug.name -> value) which was emulated by
1057	 * the sysctl(8) binary
1058	 *
1059	 * the new way, which the sysctl(8) binary was actually using
1060
1061	 node	debug
1062	 node	debug.0
1063	 string	debug.0.name
1064	 int	debug.0.value
1065	 int	debug.name
1066
1067	 */
1068
1069	sysctl_createv(clog, 0, NULL, NULL,
1070		       CTLFLAG_PERMANENT,
1071		       CTLTYPE_NODE, "debug", NULL,
1072		       NULL, 0, NULL, 0,
1073		       CTL_DEBUG, CTL_EOL);
1074
1075	for (i = 0; i < CTL_DEBUG_MAXID; i++) {
1076		cdp = debugvars[i];
1077		if (cdp->debugname == NULL || cdp->debugvar == NULL)
1078			continue;
1079
1080		snprintf(nodename, sizeof(nodename), "debug%d", i);
1081		sysctl_createv(clog, 0, NULL, NULL,
1082			       CTLFLAG_PERMANENT|CTLFLAG_HIDDEN,
1083			       CTLTYPE_NODE, nodename, NULL,
1084			       NULL, 0, NULL, 0,
1085			       CTL_DEBUG, i, CTL_EOL);
1086		sysctl_createv(clog, 0, NULL, NULL,
1087			       CTLFLAG_PERMANENT|CTLFLAG_HIDDEN,
1088			       CTLTYPE_STRING, "name", NULL,
1089			       /*XXXUNCONST*/
1090			       NULL, 0, __UNCONST(cdp->debugname), 0,
1091			       CTL_DEBUG, i, CTL_DEBUG_NAME, CTL_EOL);
1092		sysctl_createv(clog, 0, NULL, NULL,
1093			       CTLFLAG_PERMANENT|CTLFLAG_HIDDEN,
1094			       CTLTYPE_INT, "value", NULL,
1095			       NULL, 0, cdp->debugvar, 0,
1096			       CTL_DEBUG, i, CTL_DEBUG_VALUE, CTL_EOL);
1097		sysctl_createv(clog, 0, NULL, NULL,
1098			       CTLFLAG_PERMANENT,
1099			       CTLTYPE_INT, cdp->debugname, NULL,
1100			       NULL, 0, cdp->debugvar, 0,
1101			       CTL_DEBUG, CTL_CREATE, CTL_EOL);
1102	}
1103}
1104#endif /* DEBUG */
1105
1106/*
1107 * ********************************************************************
1108 * section 2: private node-specific helper routines.
1109 * ********************************************************************
1110 */
1111
1112#ifdef DIAGNOSTIC
1113static int
1114sysctl_kern_trigger_panic(SYSCTLFN_ARGS)
1115{
1116	int newtrig, error;
1117	struct sysctlnode node;
1118
1119	newtrig = 0;
1120	node = *rnode;
1121	node.sysctl_data = &newtrig;
1122	error = sysctl_lookup(SYSCTLFN_CALL(&node));
1123	if (error || newp == NULL)
1124		return (error);
1125
1126	if (newtrig != 0)
1127		panic("Panic triggered");
1128
1129	return (error);
1130}
1131#endif
1132
1133/*
1134 * sysctl helper routine for kern.maxvnodes.  drain vnodes if
1135 * new value is lower than desiredvnodes and then calls reinit
1136 * routines that needs to adjust to the new value.
1137 */
1138static int
1139sysctl_kern_maxvnodes(SYSCTLFN_ARGS)
1140{
1141	int error, new_vnodes, old_vnodes;
1142	struct sysctlnode node;
1143
1144	new_vnodes = desiredvnodes;
1145	node = *rnode;
1146	node.sysctl_data = &new_vnodes;
1147	error = sysctl_lookup(SYSCTLFN_CALL(&node));
1148	if (error || newp == NULL)
1149		return (error);
1150
1151	old_vnodes = desiredvnodes;
1152	desiredvnodes = new_vnodes;
1153	if (new_vnodes < old_vnodes) {
1154		error = vfs_drainvnodes(new_vnodes, l);
1155		if (error) {
1156			desiredvnodes = old_vnodes;
1157			return (error);
1158		}
1159	}
1160	vfs_reinit();
1161	nchreinit();
1162
1163	return (0);
1164}
1165
1166/*
1167 * sysctl helper routine for rtc_offset - set time after changes
1168 */
1169static int
1170sysctl_kern_rtc_offset(SYSCTLFN_ARGS)
1171{
1172	struct timespec ts, delta;
1173	int error, new_rtc_offset;
1174	struct sysctlnode node;
1175
1176	new_rtc_offset = rtc_offset;
1177	node = *rnode;
1178	node.sysctl_data = &new_rtc_offset;
1179	error = sysctl_lookup(SYSCTLFN_CALL(&node));
1180	if (error || newp == NULL)
1181		return (error);
1182
1183	if (kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_TIME,
1184	    KAUTH_REQ_SYSTEM_TIME_RTCOFFSET,
1185	    (void *)(u_long)new_rtc_offset, NULL, NULL))
1186		return (EPERM);
1187	if (rtc_offset == new_rtc_offset)
1188		return (0);
1189
1190	/* if we change the offset, adjust the time */
1191	nanotime(&ts);
1192	delta.tv_sec = 60 * (new_rtc_offset - rtc_offset);
1193	delta.tv_nsec = 0;
1194	timespecadd(&ts, &delta, &ts);
1195	rtc_offset = new_rtc_offset;
1196	settime(l->l_proc, &ts);
1197
1198	return (0);
1199}
1200
1201/*
1202 * sysctl helper routine for kern.maxproc.  ensures that the new
1203 * values are not too low or too high.
1204 */
1205static int
1206sysctl_kern_maxproc(SYSCTLFN_ARGS)
1207{
1208	int error, nmaxproc;
1209	struct sysctlnode node;
1210
1211	nmaxproc = maxproc;
1212	node = *rnode;
1213	node.sysctl_data = &nmaxproc;
1214	error = sysctl_lookup(SYSCTLFN_CALL(&node));
1215	if (error || newp == NULL)
1216		return (error);
1217
1218	if (nmaxproc < 0 || nmaxproc >= PID_MAX)
1219		return (EINVAL);
1220#ifdef __HAVE_CPU_MAXPROC
1221	if (nmaxproc > cpu_maxproc())
1222		return (EINVAL);
1223#endif
1224	maxproc = nmaxproc;
1225
1226	return (0);
1227}
1228
1229/*
1230 * sysctl helper function for kern.hostid.  the hostid is a long, but
1231 * we export it as an int, so we need to give it a little help.
1232 */
1233static int
1234sysctl_kern_hostid(SYSCTLFN_ARGS)
1235{
1236	int error, inthostid;
1237	struct sysctlnode node;
1238
1239	inthostid = hostid;  /* XXX assumes sizeof int <= sizeof long */
1240	node = *rnode;
1241	node.sysctl_data = &inthostid;
1242	error = sysctl_lookup(SYSCTLFN_CALL(&node));
1243	if (error || newp == NULL)
1244		return (error);
1245
1246	hostid = (unsigned)inthostid;
1247
1248	return (0);
1249}
1250
1251/*
1252 * sysctl helper function for kern.hostname and kern.domainnname.
1253 * resets the relevant recorded length when the underlying name is
1254 * changed.
1255 */
1256static int
1257sysctl_setlen(SYSCTLFN_ARGS)
1258{
1259	int error;
1260
1261	error = sysctl_lookup(SYSCTLFN_CALL(rnode));
1262	if (error || newp == NULL)
1263		return (error);
1264
1265	switch (rnode->sysctl_num) {
1266	case KERN_HOSTNAME:
1267		hostnamelen = strlen((const char*)rnode->sysctl_data);
1268		break;
1269	case KERN_DOMAINNAME:
1270		domainnamelen = strlen((const char*)rnode->sysctl_data);
1271		break;
1272	}
1273
1274	return (0);
1275}
1276
1277/*
1278 * sysctl helper routine for kern.clockrate.  assembles a struct on
1279 * the fly to be returned to the caller.
1280 */
1281static int
1282sysctl_kern_clockrate(SYSCTLFN_ARGS)
1283{
1284	struct clockinfo clkinfo;
1285	struct sysctlnode node;
1286
1287	clkinfo.tick = tick;
1288	clkinfo.tickadj = tickadj;
1289	clkinfo.hz = hz;
1290	clkinfo.profhz = profhz;
1291	clkinfo.stathz = stathz ? stathz : hz;
1292
1293	node = *rnode;
1294	node.sysctl_data = &clkinfo;
1295	return (sysctl_lookup(SYSCTLFN_CALL(&node)));
1296}
1297
1298
1299/*
1300 * sysctl helper routine for kern.file pseudo-subtree.
1301 */
1302static int
1303sysctl_kern_file(SYSCTLFN_ARGS)
1304{
1305	int error;
1306	size_t buflen;
1307	struct file *fp;
1308	char *start, *where;
1309
1310	start = where = oldp;
1311	buflen = *oldlenp;
1312	if (where == NULL) {
1313		/*
1314		 * overestimate by 10 files
1315		 */
1316		*oldlenp = sizeof(filehead) + (nfiles + 10) * sizeof(struct file);
1317		return (0);
1318	}
1319
1320	/*
1321	 * first dcopyout filehead
1322	 */
1323	if (buflen < sizeof(filehead)) {
1324		*oldlenp = 0;
1325		return (0);
1326	}
1327	error = dcopyout(l, &filehead, where, sizeof(filehead));
1328	if (error)
1329		return (error);
1330	buflen -= sizeof(filehead);
1331	where += sizeof(filehead);
1332
1333	/*
1334	 * followed by an array of file structures
1335	 */
1336	LIST_FOREACH(fp, &filehead, f_list) {
1337		if (kauth_authorize_generic(l->l_cred,
1338		    KAUTH_GENERIC_CANSEE, fp->f_cred) != 0)
1339			continue;
1340		if (buflen < sizeof(struct file)) {
1341			*oldlenp = where - start;
1342			return (ENOMEM);
1343		}
1344		error = dcopyout(l, fp, where, sizeof(struct file));
1345		if (error)
1346			return (error);
1347		buflen -= sizeof(struct file);
1348		where += sizeof(struct file);
1349	}
1350	*oldlenp = where - start;
1351	return (0);
1352}
1353
1354/*
1355 * sysctl helper routine for kern.autonicetime and kern.autoniceval.
1356 * asserts that the assigned value is in the correct range.
1357 */
1358static int
1359sysctl_kern_autonice(SYSCTLFN_ARGS)
1360{
1361	int error, t = 0;
1362	struct sysctlnode node;
1363
1364	node = *rnode;
1365	t = *(int*)node.sysctl_data;
1366	node.sysctl_data = &t;
1367	error = sysctl_lookup(SYSCTLFN_CALL(&node));
1368	if (error || newp == NULL)
1369		return (error);
1370
1371	switch (node.sysctl_num) {
1372	case KERN_AUTONICETIME:
1373		if (t >= 0)
1374			autonicetime = t;
1375		break;
1376	case KERN_AUTONICEVAL:
1377		if (t < PRIO_MIN)
1378			t = PRIO_MIN;
1379		else if (t > PRIO_MAX)
1380			t = PRIO_MAX;
1381		autoniceval = t;
1382		break;
1383	}
1384
1385	return (0);
1386}
1387
1388/*
1389 * sysctl helper routine for kern.msgbufsize and kern.msgbuf.  for the
1390 * former it merely checks the message buffer is set up.  for the latter,
1391 * it also copies out the data if necessary.
1392 */
1393static int
1394sysctl_msgbuf(SYSCTLFN_ARGS)
1395{
1396	char *where = oldp;
1397	size_t len, maxlen;
1398	long beg, end;
1399	int error;
1400
1401	if (!msgbufenabled || msgbufp->msg_magic != MSG_MAGIC) {
1402		msgbufenabled = 0;
1403		return (ENXIO);
1404	}
1405
1406	switch (rnode->sysctl_num) {
1407	case KERN_MSGBUFSIZE: {
1408		struct sysctlnode node = *rnode;
1409		int msg_bufs = (int)msgbufp->msg_bufs;
1410		node.sysctl_data = &msg_bufs;
1411		return (sysctl_lookup(SYSCTLFN_CALL(&node)));
1412	}
1413	case KERN_MSGBUF:
1414		break;
1415	default:
1416		return (EOPNOTSUPP);
1417	}
1418
1419	if (newp != NULL)
1420		return (EPERM);
1421
1422        if (oldp == NULL) {
1423		/* always return full buffer size */
1424		*oldlenp = msgbufp->msg_bufs;
1425		return (0);
1426        }
1427
1428	error = 0;
1429	maxlen = MIN(msgbufp->msg_bufs, *oldlenp);
1430
1431	/*
1432	 * First, copy from the write pointer to the end of
1433	 * message buffer.
1434	 */
1435	beg = msgbufp->msg_bufx;
1436	end = msgbufp->msg_bufs;
1437	while (maxlen > 0) {
1438		len = MIN(end - beg, maxlen);
1439		if (len == 0)
1440			break;
1441		error = dcopyout(l, &msgbufp->msg_bufc[beg], where, len);
1442		if (error)
1443			break;
1444		where += len;
1445		maxlen -= len;
1446
1447		/*
1448		 * ... then, copy from the beginning of message buffer to
1449		 * the write pointer.
1450		 */
1451		beg = 0;
1452		end = msgbufp->msg_bufx;
1453	}
1454
1455	return (error);
1456}
1457
1458/*
1459 * sysctl helper routine for kern.defcorename.  in the case of a new
1460 * string being assigned, check that it's not a zero-length string.
1461 * (XXX the check in -current doesn't work, but do we really care?)
1462 */
1463static int
1464sysctl_kern_defcorename(SYSCTLFN_ARGS)
1465{
1466	int error;
1467	char *newcorename;
1468	struct sysctlnode node;
1469
1470	newcorename = PNBUF_GET();
1471	node = *rnode;
1472	node.sysctl_data = &newcorename[0];
1473	memcpy(node.sysctl_data, rnode->sysctl_data, MAXPATHLEN);
1474	error = sysctl_lookup(SYSCTLFN_CALL(&node));
1475	if (error || newp == NULL) {
1476		goto done;
1477	}
1478
1479	/*
1480	 * when sysctl_lookup() deals with a string, it's guaranteed
1481	 * to come back nul terminated.  so there.  :)
1482	 */
1483	if (strlen(newcorename) == 0) {
1484		error = EINVAL;
1485	} else {
1486		memcpy(rnode->sysctl_data, node.sysctl_data, MAXPATHLEN);
1487		error = 0;
1488	}
1489done:
1490	PNBUF_PUT(newcorename);
1491	return error;
1492}
1493
1494/*
1495 * sysctl helper routine for kern.cp_time node.  adds up cpu time
1496 * across all cpus.
1497 */
1498static int
1499sysctl_kern_cptime(SYSCTLFN_ARGS)
1500{
1501	struct sysctlnode node = *rnode;
1502
1503#ifndef MULTIPROCESSOR
1504
1505	if (namelen == 1) {
1506		if (name[0] != 0)
1507			return (ENOENT);
1508		/*
1509		 * you're allowed to ask for the zero'th processor
1510		 */
1511		name++;
1512		namelen--;
1513	}
1514	node.sysctl_data = curcpu()->ci_schedstate.spc_cp_time;
1515	node.sysctl_size = sizeof(curcpu()->ci_schedstate.spc_cp_time);
1516	return (sysctl_lookup(SYSCTLFN_CALL(&node)));
1517
1518#else /* MULTIPROCESSOR */
1519
1520	uint64_t *cp_time = NULL;
1521	int error, n = sysctl_ncpus(), i;
1522	struct cpu_info *ci;
1523	CPU_INFO_ITERATOR cii;
1524
1525	/*
1526	 * if you specifically pass a buffer that is the size of the
1527	 * sum, or if you are probing for the size, you get the "sum"
1528	 * of cp_time (and the size thereof) across all processors.
1529	 *
1530	 * alternately, you can pass an additional mib number and get
1531	 * cp_time for that particular processor.
1532	 */
1533	switch (namelen) {
1534	case 0:
1535	    	if (*oldlenp == sizeof(uint64_t) * CPUSTATES || oldp == NULL) {
1536			node.sysctl_size = sizeof(uint64_t) * CPUSTATES;
1537			n = -1; /* SUM */
1538		}
1539		else {
1540			node.sysctl_size = n * sizeof(uint64_t) * CPUSTATES;
1541			n = -2; /* ALL */
1542		}
1543		break;
1544	case 1:
1545		if (name[0] < 0 || name[0] >= n)
1546			return (ENOENT); /* ENOSUCHPROCESSOR */
1547		node.sysctl_size = sizeof(uint64_t) * CPUSTATES;
1548		n = name[0];
1549		/*
1550		 * adjust these so that sysctl_lookup() will be happy
1551		 */
1552		name++;
1553		namelen--;
1554		break;
1555	default:
1556		return (EINVAL);
1557	}
1558
1559	cp_time = malloc(node.sysctl_size, M_TEMP, M_WAITOK|M_CANFAIL);
1560	if (cp_time == NULL)
1561		return (ENOMEM);
1562	node.sysctl_data = cp_time;
1563	memset(cp_time, 0, node.sysctl_size);
1564
1565	for (CPU_INFO_FOREACH(cii, ci)) {
1566		if (n <= 0)
1567			for (i = 0; i < CPUSTATES; i++)
1568				cp_time[i] += ci->ci_schedstate.spc_cp_time[i];
1569		/*
1570		 * if a specific processor was requested and we just
1571		 * did it, we're done here
1572		 */
1573		if (n == 0)
1574			break;
1575		/*
1576		 * if doing "all", skip to next cp_time set for next processor
1577		 */
1578		if (n == -2)
1579			cp_time += CPUSTATES;
1580		/*
1581		 * if we're doing a specific processor, we're one
1582		 * processor closer
1583		 */
1584		if (n > 0)
1585			n--;
1586	}
1587
1588	error = sysctl_lookup(SYSCTLFN_CALL(&node));
1589	free(node.sysctl_data, M_TEMP);
1590	return (error);
1591
1592#endif /* MULTIPROCESSOR */
1593}
1594
1595#if defined(SYSVMSG) || defined(SYSVSEM) || defined(SYSVSHM)
1596/*
1597 * sysctl helper routine for kern.sysvipc_info subtree.
1598 */
1599
1600#define	FILL_PERM(src, dst) do { \
1601	(dst)._key = (src)._key; \
1602	(dst).uid = (src).uid; \
1603	(dst).gid = (src).gid; \
1604	(dst).cuid = (src).cuid; \
1605	(dst).cgid = (src).cgid; \
1606	(dst).mode = (src).mode; \
1607	(dst)._seq = (src)._seq; \
1608} while (/*CONSTCOND*/ 0);
1609#define	FILL_MSG(src, dst) do { \
1610	FILL_PERM((src).msg_perm, (dst).msg_perm); \
1611	(dst).msg_qnum = (src).msg_qnum; \
1612	(dst).msg_qbytes = (src).msg_qbytes; \
1613	(dst)._msg_cbytes = (src)._msg_cbytes; \
1614	(dst).msg_lspid = (src).msg_lspid; \
1615	(dst).msg_lrpid = (src).msg_lrpid; \
1616	(dst).msg_stime = (src).msg_stime; \
1617	(dst).msg_rtime = (src).msg_rtime; \
1618	(dst).msg_ctime = (src).msg_ctime; \
1619} while (/*CONSTCOND*/ 0)
1620#define	FILL_SEM(src, dst) do { \
1621	FILL_PERM((src).sem_perm, (dst).sem_perm); \
1622	(dst).sem_nsems = (src).sem_nsems; \
1623	(dst).sem_otime = (src).sem_otime; \
1624	(dst).sem_ctime = (src).sem_ctime; \
1625} while (/*CONSTCOND*/ 0)
1626#define	FILL_SHM(src, dst) do { \
1627	FILL_PERM((src).shm_perm, (dst).shm_perm); \
1628	(dst).shm_segsz = (src).shm_segsz; \
1629	(dst).shm_lpid = (src).shm_lpid; \
1630	(dst).shm_cpid = (src).shm_cpid; \
1631	(dst).shm_atime = (src).shm_atime; \
1632	(dst).shm_dtime = (src).shm_dtime; \
1633	(dst).shm_ctime = (src).shm_ctime; \
1634	(dst).shm_nattch = (src).shm_nattch; \
1635} while (/*CONSTCOND*/ 0)
1636
1637static int
1638sysctl_kern_sysvipc(SYSCTLFN_ARGS)
1639{
1640	void *where = oldp;
1641	size_t *sizep = oldlenp;
1642#ifdef SYSVMSG
1643	struct msg_sysctl_info *msgsi = NULL;
1644#endif
1645#ifdef SYSVSEM
1646	struct sem_sysctl_info *semsi = NULL;
1647#endif
1648#ifdef SYSVSHM
1649	struct shm_sysctl_info *shmsi = NULL;
1650#endif
1651	size_t infosize, dssize, tsize, buflen;
1652	void *bf = NULL;
1653	char *start;
1654	int32_t nds;
1655	int i, error, ret;
1656
1657	if (namelen != 1)
1658		return (EINVAL);
1659
1660	start = where;
1661	buflen = *sizep;
1662
1663	switch (*name) {
1664	case KERN_SYSVIPC_MSG_INFO:
1665#ifdef SYSVMSG
1666		infosize = sizeof(msgsi->msginfo);
1667		nds = msginfo.msgmni;
1668		dssize = sizeof(msgsi->msgids[0]);
1669		break;
1670#else
1671		return (EINVAL);
1672#endif
1673	case KERN_SYSVIPC_SEM_INFO:
1674#ifdef SYSVSEM
1675		infosize = sizeof(semsi->seminfo);
1676		nds = seminfo.semmni;
1677		dssize = sizeof(semsi->semids[0]);
1678		break;
1679#else
1680		return (EINVAL);
1681#endif
1682	case KERN_SYSVIPC_SHM_INFO:
1683#ifdef SYSVSHM
1684		infosize = sizeof(shmsi->shminfo);
1685		nds = shminfo.shmmni;
1686		dssize = sizeof(shmsi->shmids[0]);
1687		break;
1688#else
1689		return (EINVAL);
1690#endif
1691	default:
1692		return (EINVAL);
1693	}
1694	/*
1695	 * Round infosize to 64 bit boundary if requesting more than just
1696	 * the info structure or getting the total data size.
1697	 */
1698	if (where == NULL || *sizep > infosize)
1699		infosize = ((infosize + 7) / 8) * 8;
1700	tsize = infosize + nds * dssize;
1701
1702	/* Return just the total size required. */
1703	if (where == NULL) {
1704		*sizep = tsize;
1705		return (0);
1706	}
1707
1708	/* Not enough room for even the info struct. */
1709	if (buflen < infosize) {
1710		*sizep = 0;
1711		return (ENOMEM);
1712	}
1713	bf = malloc(min(tsize, buflen), M_TEMP, M_WAITOK);
1714	memset(bf, 0, min(tsize, buflen));
1715
1716	switch (*name) {
1717#ifdef SYSVMSG
1718	case KERN_SYSVIPC_MSG_INFO:
1719		msgsi = (struct msg_sysctl_info *)bf;
1720		msgsi->msginfo = msginfo;
1721		break;
1722#endif
1723#ifdef SYSVSEM
1724	case KERN_SYSVIPC_SEM_INFO:
1725		semsi = (struct sem_sysctl_info *)bf;
1726		semsi->seminfo = seminfo;
1727		break;
1728#endif
1729#ifdef SYSVSHM
1730	case KERN_SYSVIPC_SHM_INFO:
1731		shmsi = (struct shm_sysctl_info *)bf;
1732		shmsi->shminfo = shminfo;
1733		break;
1734#endif
1735	}
1736	buflen -= infosize;
1737
1738	ret = 0;
1739	if (buflen > 0) {
1740		/* Fill in the IPC data structures.  */
1741		for (i = 0; i < nds; i++) {
1742			if (buflen < dssize) {
1743				ret = ENOMEM;
1744				break;
1745			}
1746			switch (*name) {
1747#ifdef SYSVMSG
1748			case KERN_SYSVIPC_MSG_INFO:
1749				FILL_MSG(msqids[i], msgsi->msgids[i]);
1750				break;
1751#endif
1752#ifdef SYSVSEM
1753			case KERN_SYSVIPC_SEM_INFO:
1754				FILL_SEM(sema[i], semsi->semids[i]);
1755				break;
1756#endif
1757#ifdef SYSVSHM
1758			case KERN_SYSVIPC_SHM_INFO:
1759				FILL_SHM(shmsegs[i], shmsi->shmids[i]);
1760				break;
1761#endif
1762			}
1763			buflen -= dssize;
1764		}
1765	}
1766	*sizep -= buflen;
1767	error = dcopyout(l, bf, start, *sizep);
1768	/* If dcopyout succeeded, use return code set earlier. */
1769	if (error == 0)
1770		error = ret;
1771	if (bf)
1772		free(bf, M_TEMP);
1773	return (error);
1774}
1775
1776#undef FILL_PERM
1777#undef FILL_MSG
1778#undef FILL_SEM
1779#undef FILL_SHM
1780
1781#endif /* defined(SYSVMSG) || defined(SYSVSEM) || defined(SYSVSHM) */
1782
1783#if NPTY > 0
1784/*
1785 * sysctl helper routine for kern.maxptys.  ensures that any new value
1786 * is acceptable to the pty subsystem.
1787 */
1788static int
1789sysctl_kern_maxptys(SYSCTLFN_ARGS)
1790{
1791	int pty_maxptys(int, int);		/* defined in kern/tty_pty.c */
1792	int error, xmax;
1793	struct sysctlnode node;
1794
1795	/* get current value of maxptys */
1796	xmax = pty_maxptys(0, 0);
1797
1798	node = *rnode;
1799	node.sysctl_data = &xmax;
1800	error = sysctl_lookup(SYSCTLFN_CALL(&node));
1801	if (error || newp == NULL)
1802		return (error);
1803
1804	if (xmax != pty_maxptys(xmax, 1))
1805		return (EINVAL);
1806
1807	return (0);
1808}
1809#endif /* NPTY > 0 */
1810
1811/*
1812 * sysctl helper routine for kern.sbmax.  basically just ensures that
1813 * any new value is not too small.
1814 */
1815static int
1816sysctl_kern_sbmax(SYSCTLFN_ARGS)
1817{
1818	int error, new_sbmax;
1819	struct sysctlnode node;
1820
1821	new_sbmax = sb_max;
1822	node = *rnode;
1823	node.sysctl_data = &new_sbmax;
1824	error = sysctl_lookup(SYSCTLFN_CALL(&node));
1825	if (error || newp == NULL)
1826		return (error);
1827
1828	error = sb_max_set(new_sbmax);
1829
1830	return (error);
1831}
1832
1833/*
1834 * sysctl helper routine for kern.urandom node.  picks a random number
1835 * for you.
1836 */
1837static int
1838sysctl_kern_urnd(SYSCTLFN_ARGS)
1839{
1840#if NRND > 0
1841	int v;
1842
1843	if (rnd_extract_data(&v, sizeof(v), RND_EXTRACT_ANY) == sizeof(v)) {
1844		struct sysctlnode node = *rnode;
1845		node.sysctl_data = &v;
1846		return (sysctl_lookup(SYSCTLFN_CALL(&node)));
1847	}
1848	else
1849		return (EIO);	/*XXX*/
1850#else
1851	return (EOPNOTSUPP);
1852#endif
1853}
1854
1855/*
1856 * sysctl helper routine to do kern.lwp.* work.
1857 */
1858static int
1859sysctl_kern_lwp(SYSCTLFN_ARGS)
1860{
1861	struct kinfo_lwp klwp;
1862	struct proc *p;
1863	struct lwp *l2;
1864	char *where, *dp;
1865	int pid, elem_size, elem_count;
1866	int buflen, needed, error;
1867
1868	if (namelen == 1 && name[0] == CTL_QUERY)
1869		return (sysctl_query(SYSCTLFN_CALL(rnode)));
1870
1871	dp = where = oldp;
1872	buflen = where != NULL ? *oldlenp : 0;
1873	error = needed = 0;
1874
1875	if (newp != NULL || namelen != 3)
1876		return (EINVAL);
1877	pid = name[0];
1878	elem_size = name[1];
1879	elem_count = name[2];
1880
1881	p = pfind(pid);
1882	if (p == NULL)
1883		return (ESRCH);
1884	LIST_FOREACH(l2, &p->p_lwps, l_sibling) {
1885		if (buflen >= elem_size && elem_count > 0) {
1886			fill_lwp(l2, &klwp);
1887			/*
1888			 * Copy out elem_size, but not larger than
1889			 * the size of a struct kinfo_proc2.
1890			 */
1891			error = dcopyout(l, &klwp, dp,
1892			    min(sizeof(klwp), elem_size));
1893			if (error)
1894				goto cleanup;
1895			dp += elem_size;
1896			buflen -= elem_size;
1897			elem_count--;
1898		}
1899		needed += elem_size;
1900	}
1901
1902	if (where != NULL) {
1903		*oldlenp = dp - where;
1904		if (needed > *oldlenp)
1905			return (ENOMEM);
1906	} else {
1907		needed += KERN_LWPSLOP;
1908		*oldlenp = needed;
1909	}
1910	return (0);
1911 cleanup:
1912	return (error);
1913}
1914
1915/*
1916 * sysctl helper routine for kern.forkfsleep node.  ensures that the
1917 * given value is not too large or two small, and is at least one
1918 * timer tick if not zero.
1919 */
1920static int
1921sysctl_kern_forkfsleep(SYSCTLFN_ARGS)
1922{
1923	/* userland sees value in ms, internally is in ticks */
1924	extern int forkfsleep;		/* defined in kern/kern_fork.c */
1925	int error, timo, lsleep;
1926	struct sysctlnode node;
1927
1928	lsleep = forkfsleep * 1000 / hz;
1929	node = *rnode;
1930	node.sysctl_data = &lsleep;
1931	error = sysctl_lookup(SYSCTLFN_CALL(&node));
1932	if (error || newp == NULL)
1933		return (error);
1934
1935	/* refuse negative values, and overly 'long time' */
1936	if (lsleep < 0 || lsleep > MAXSLP * 1000)
1937		return (EINVAL);
1938
1939	timo = mstohz(lsleep);
1940
1941	/* if the interval is >0 ms && <1 tick, use 1 tick */
1942	if (lsleep != 0 && timo == 0)
1943		forkfsleep = 1;
1944	else
1945		forkfsleep = timo;
1946
1947	return (0);
1948}
1949
1950/*
1951 * sysctl helper routine for kern.root_partition
1952 */
1953static int
1954sysctl_kern_root_partition(SYSCTLFN_ARGS)
1955{
1956	int rootpart = DISKPART(rootdev);
1957	struct sysctlnode node = *rnode;
1958
1959	node.sysctl_data = &rootpart;
1960	return (sysctl_lookup(SYSCTLFN_CALL(&node)));
1961}
1962
1963/*
1964 * sysctl helper function for kern.drivers
1965 */
1966static int
1967sysctl_kern_drivers(SYSCTLFN_ARGS)
1968{
1969	int error;
1970	size_t buflen;
1971	struct kinfo_drivers kd;
1972	char *start, *where;
1973	const char *dname;
1974	int i;
1975	extern struct devsw_conv *devsw_conv;
1976	extern int max_devsw_convs;
1977
1978	if (newp != NULL || namelen != 0)
1979		return (EINVAL);
1980
1981	start = where = oldp;
1982	buflen = *oldlenp;
1983	if (where == NULL) {
1984		*oldlenp = max_devsw_convs * sizeof kd;
1985		return 0;
1986	}
1987
1988	/*
1989	 * An array of kinfo_drivers structures
1990	 */
1991	error = 0;
1992	for (i = 0; i < max_devsw_convs; i++) {
1993		dname = devsw_conv[i].d_name;
1994		if (dname == NULL)
1995			continue;
1996		if (buflen < sizeof kd) {
1997			error = ENOMEM;
1998			break;
1999		}
2000		memset(&kd, 0, sizeof(kd));
2001		kd.d_bmajor = devsw_conv[i].d_bmajor;
2002		kd.d_cmajor = devsw_conv[i].d_cmajor;
2003		strlcpy(kd.d_name, dname, sizeof kd.d_name);
2004		error = dcopyout(l, &kd, where, sizeof kd);
2005		if (error != 0)
2006			break;
2007		buflen -= sizeof kd;
2008		where += sizeof kd;
2009	}
2010	*oldlenp = where - start;
2011	return error;
2012}
2013
2014/*
2015 * sysctl helper function for kern.file2
2016 */
2017static int
2018sysctl_kern_file2(SYSCTLFN_ARGS)
2019{
2020	struct proc *p;
2021	struct file *fp;
2022	struct filedesc *fd;
2023	struct kinfo_file kf;
2024	char *dp;
2025	u_int i, op;
2026	size_t len, needed, elem_size, out_size;
2027	int error, arg, elem_count;
2028
2029	if (namelen == 1 && name[0] == CTL_QUERY)
2030		return (sysctl_query(SYSCTLFN_CALL(rnode)));
2031
2032	if (namelen != 4)
2033		return (EINVAL);
2034
2035	error = 0;
2036	dp = oldp;
2037	len = (oldp != NULL) ? *oldlenp : 0;
2038	op = name[0];
2039	arg = name[1];
2040	elem_size = name[2];
2041	elem_count = name[3];
2042	out_size = MIN(sizeof(kf), elem_size);
2043	needed = 0;
2044
2045	if (elem_size < 1 || elem_count < 0)
2046		return (EINVAL);
2047
2048	switch (op) {
2049	case KERN_FILE_BYFILE:
2050		/*
2051		 * doesn't use arg so it must be zero
2052		 */
2053		if (arg != 0)
2054			return (EINVAL);
2055		LIST_FOREACH(fp, &filehead, f_list) {
2056			if (kauth_authorize_generic(l->l_cred,
2057			    KAUTH_GENERIC_CANSEE, fp->f_cred) != 0)
2058				continue;
2059			if (len >= elem_size && elem_count > 0) {
2060				fill_file(&kf, fp, NULL, 0);
2061				error = dcopyout(l, &kf, dp, out_size);
2062				if (error)
2063					break;
2064				dp += elem_size;
2065				len -= elem_size;
2066			}
2067			if (elem_count > 0) {
2068				needed += elem_size;
2069				if (elem_count != INT_MAX)
2070					elem_count--;
2071			}
2072		}
2073		break;
2074	case KERN_FILE_BYPID:
2075		if (arg < -1)
2076			/* -1 means all processes */
2077			return (EINVAL);
2078		proclist_lock_read();
2079		PROCLIST_FOREACH(p, &allproc) {
2080			if (p->p_stat == SIDL)
2081				/* skip embryonic processes */
2082				continue;
2083			if (kauth_authorize_process(l->l_cred,
2084			    KAUTH_PROCESS_CANSEE, p, NULL, NULL, NULL) != 0)
2085				continue;
2086			if (arg > 0 && p->p_pid != arg)
2087				/* pick only the one we want */
2088				/* XXX want 0 to mean "kernel files" */
2089				continue;
2090			fd = p->p_fd;
2091			for (i = 0; i < fd->fd_nfiles; i++) {
2092				fp = fd->fd_ofiles[i];
2093				if (fp == NULL || !FILE_IS_USABLE(fp))
2094					continue;
2095				if (len >= elem_size && elem_count > 0) {
2096					fill_file(&kf, fd->fd_ofiles[i],
2097						  p, i);
2098					error = dcopyout(l, &kf, dp, out_size);
2099					if (error)
2100						break;
2101					dp += elem_size;
2102					len -= elem_size;
2103				}
2104				if (elem_count > 0) {
2105					needed += elem_size;
2106					if (elem_count != INT_MAX)
2107						elem_count--;
2108				}
2109			}
2110		}
2111		proclist_unlock_read();
2112		break;
2113	default:
2114		return (EINVAL);
2115	}
2116
2117	if (oldp == NULL)
2118		needed += KERN_FILESLOP * elem_size;
2119	*oldlenp = needed;
2120
2121	return (error);
2122}
2123
2124static void
2125fill_file(struct kinfo_file *kp, const struct file *fp, struct proc *p, int i)
2126{
2127
2128	memset(kp, 0, sizeof(*kp));
2129
2130	kp->ki_fileaddr =	PTRTOUINT64(fp);
2131	kp->ki_flag =		fp->f_flag;
2132	kp->ki_iflags =		fp->f_iflags;
2133	kp->ki_ftype =		fp->f_type;
2134	kp->ki_count =		fp->f_count;
2135	kp->ki_msgcount =	fp->f_msgcount;
2136	kp->ki_usecount =	fp->f_usecount;
2137	kp->ki_fucred =		PTRTOUINT64(fp->f_cred);
2138	kp->ki_fuid =		kauth_cred_geteuid(fp->f_cred);
2139	kp->ki_fgid =		kauth_cred_getegid(fp->f_cred);
2140	kp->ki_fops =		PTRTOUINT64(fp->f_ops);
2141	kp->ki_foffset =	fp->f_offset;
2142	kp->ki_fdata =		PTRTOUINT64(fp->f_data);
2143
2144	/* vnode information to glue this file to something */
2145	if (fp->f_type == DTYPE_VNODE) {
2146		struct vnode *vp = (struct vnode *)fp->f_data;
2147
2148		kp->ki_vun =	PTRTOUINT64(vp->v_un.vu_socket);
2149		kp->ki_vsize =	vp->v_size;
2150		kp->ki_vtype =	vp->v_type;
2151		kp->ki_vtag =	vp->v_tag;
2152		kp->ki_vdata =	PTRTOUINT64(vp->v_data);
2153	}
2154
2155        /* process information when retrieved via KERN_FILE_BYPID */
2156	if (p) {
2157		kp->ki_pid =		p->p_pid;
2158		kp->ki_fd =		i;
2159		kp->ki_ofileflags =	p->p_fd->fd_ofileflags[i];
2160	}
2161}
2162
2163static int
2164sysctl_doeproc(SYSCTLFN_ARGS)
2165{
2166	struct eproc *eproc;
2167	struct kinfo_proc2 *kproc2;
2168	struct kinfo_proc *dp;
2169	struct proc *p;
2170	const struct proclist_desc *pd;
2171	char *where, *dp2;
2172	int type, op, arg;
2173	u_int elem_size, elem_count;
2174	size_t buflen, needed;
2175	int error;
2176
2177	if (namelen == 1 && name[0] == CTL_QUERY)
2178		return (sysctl_query(SYSCTLFN_CALL(rnode)));
2179
2180	dp = oldp;
2181	dp2 = where = oldp;
2182	buflen = where != NULL ? *oldlenp : 0;
2183	error = 0;
2184	needed = 0;
2185	type = rnode->sysctl_num;
2186
2187	if (type == KERN_PROC) {
2188		if (namelen != 2 && !(namelen == 1 && name[0] == KERN_PROC_ALL))
2189			return (EINVAL);
2190		op = name[0];
2191		if (op != KERN_PROC_ALL)
2192			arg = name[1];
2193		else
2194			arg = 0;		/* Quell compiler warning */
2195		elem_size = elem_count = 0;	/* Ditto */
2196	} else {
2197		if (namelen != 4)
2198			return (EINVAL);
2199		op = name[0];
2200		arg = name[1];
2201		elem_size = name[2];
2202		elem_count = name[3];
2203	}
2204
2205	if (type == KERN_PROC) {
2206		eproc = malloc(sizeof(*eproc), M_TEMP, M_WAITOK);
2207		kproc2 = NULL;
2208	} else {
2209		eproc = NULL;
2210		kproc2 = malloc(sizeof(*kproc2), M_TEMP, M_WAITOK);
2211	}
2212	proclist_lock_read();
2213
2214	pd = proclists;
2215again:
2216	PROCLIST_FOREACH(p, pd->pd_list) {
2217		/*
2218		 * Skip embryonic processes.
2219		 */
2220		if (p->p_stat == SIDL)
2221			continue;
2222
2223		if (kauth_authorize_process(l->l_cred,
2224		    KAUTH_PROCESS_CANSEE, p, NULL, NULL, NULL) != 0)
2225			continue;
2226
2227		/*
2228		 * TODO - make more efficient (see notes below).
2229		 * do by session.
2230		 */
2231		switch (op) {
2232
2233		case KERN_PROC_PID:
2234			/* could do this with just a lookup */
2235			if (p->p_pid != (pid_t)arg)
2236				continue;
2237			break;
2238
2239		case KERN_PROC_PGRP:
2240			/* could do this by traversing pgrp */
2241			if (p->p_pgrp->pg_id != (pid_t)arg)
2242				continue;
2243			break;
2244
2245		case KERN_PROC_SESSION:
2246			if (p->p_session->s_sid != (pid_t)arg)
2247				continue;
2248			break;
2249
2250		case KERN_PROC_TTY:
2251			if (arg == (int) KERN_PROC_TTY_REVOKE) {
2252				if ((p->p_flag & P_CONTROLT) == 0 ||
2253				    p->p_session->s_ttyp == NULL ||
2254				    p->p_session->s_ttyvp != NULL)
2255					continue;
2256			} else if ((p->p_flag & P_CONTROLT) == 0 ||
2257			    p->p_session->s_ttyp == NULL) {
2258				if ((dev_t)arg != KERN_PROC_TTY_NODEV)
2259					continue;
2260			} else if (p->p_session->s_ttyp->t_dev != (dev_t)arg)
2261				continue;
2262			break;
2263
2264		case KERN_PROC_UID:
2265			if (kauth_cred_geteuid(p->p_cred) != (uid_t)arg)
2266				continue;
2267			break;
2268
2269		case KERN_PROC_RUID:
2270			if (kauth_cred_getuid(p->p_cred) != (uid_t)arg)
2271				continue;
2272			break;
2273
2274		case KERN_PROC_GID:
2275			if (kauth_cred_getegid(p->p_cred) != (uid_t)arg)
2276				continue;
2277			break;
2278
2279		case KERN_PROC_RGID:
2280			if (kauth_cred_getgid(p->p_cred) != (uid_t)arg)
2281				continue;
2282			break;
2283
2284		case KERN_PROC_ALL:
2285			/* allow everything */
2286			break;
2287
2288		default:
2289			error = EINVAL;
2290			goto cleanup;
2291		}
2292		if (type == KERN_PROC) {
2293			if (buflen >= sizeof(struct kinfo_proc)) {
2294				fill_eproc(p, eproc);
2295				error = dcopyout(l, p, &dp->kp_proc,
2296				    sizeof(struct proc));
2297				if (error)
2298					goto cleanup;
2299				error = dcopyout(l, eproc, &dp->kp_eproc,
2300				    sizeof(*eproc));
2301				if (error)
2302					goto cleanup;
2303				dp++;
2304				buflen -= sizeof(struct kinfo_proc);
2305			}
2306			needed += sizeof(struct kinfo_proc);
2307		} else { /* KERN_PROC2 */
2308			if (buflen >= elem_size && elem_count > 0) {
2309				fill_kproc2(p, kproc2);
2310				/*
2311				 * Copy out elem_size, but not larger than
2312				 * the size of a struct kinfo_proc2.
2313				 */
2314				error = dcopyout(l, kproc2, dp2,
2315				    min(sizeof(*kproc2), elem_size));
2316				if (error)
2317					goto cleanup;
2318				dp2 += elem_size;
2319				buflen -= elem_size;
2320				elem_count--;
2321			}
2322			needed += elem_size;
2323		}
2324	}
2325	pd++;
2326	if (pd->pd_list != NULL)
2327		goto again;
2328	proclist_unlock_read();
2329
2330	if (where != NULL) {
2331		if (type == KERN_PROC)
2332			*oldlenp = (char *)dp - where;
2333		else
2334			*oldlenp = dp2 - where;
2335		if (needed > *oldlenp) {
2336			error = ENOMEM;
2337			goto out;
2338		}
2339	} else {
2340		needed += KERN_PROCSLOP;
2341		*oldlenp = needed;
2342	}
2343	if (kproc2)
2344		free(kproc2, M_TEMP);
2345	if (eproc)
2346		free(eproc, M_TEMP);
2347	return 0;
2348 cleanup:
2349	proclist_unlock_read();
2350 out:
2351	if (kproc2)
2352		free(kproc2, M_TEMP);
2353	if (eproc)
2354		free(eproc, M_TEMP);
2355	return error;
2356}
2357
2358/*
2359 * sysctl helper routine for kern.proc_args pseudo-subtree.
2360 */
2361static int
2362sysctl_kern_proc_args(SYSCTLFN_ARGS)
2363{
2364	struct ps_strings pss;
2365	struct proc *p;
2366	size_t len, i;
2367	struct uio auio;
2368	struct iovec aiov;
2369	pid_t pid;
2370	int nargv, type, error;
2371	char *arg;
2372	char **argv = NULL;
2373	char *tmp;
2374	struct vmspace *vmspace;
2375	vaddr_t psstr_addr;
2376	vaddr_t offsetn;
2377	vaddr_t offsetv;
2378
2379	if (namelen == 1 && name[0] == CTL_QUERY)
2380		return (sysctl_query(SYSCTLFN_CALL(rnode)));
2381
2382	if (newp != NULL || namelen != 2)
2383		return (EINVAL);
2384	pid = name[0];
2385	type = name[1];
2386
2387	switch (type) {
2388	case KERN_PROC_ARGV:
2389	case KERN_PROC_NARGV:
2390	case KERN_PROC_ENV:
2391	case KERN_PROC_NENV:
2392		/* ok */
2393		break;
2394	default:
2395		return (EINVAL);
2396	}
2397
2398	proclist_lock_read();
2399
2400	/* check pid */
2401	if ((p = p_find(pid, PFIND_LOCKED)) == NULL) {
2402		error = EINVAL;
2403		goto out_locked;
2404	}
2405
2406	error = kauth_authorize_process(l->l_cred,
2407	    KAUTH_PROCESS_CANSEE, p, NULL, NULL, NULL);
2408	if (error) {
2409		goto out_locked;
2410	}
2411
2412	/* only root or same user change look at the environment */
2413	if (type == KERN_PROC_ENV || type == KERN_PROC_NENV) {
2414		if (kauth_authorize_process(l->l_cred, KAUTH_PROCESS_CANSEE,
2415		     p, NULL, NULL, NULL)) {
2416				error = EPERM;
2417				goto out_locked;
2418		}
2419	}
2420
2421	if (oldp == NULL) {
2422		if (type == KERN_PROC_NARGV || type == KERN_PROC_NENV)
2423			*oldlenp = sizeof (int);
2424		else
2425			*oldlenp = ARG_MAX;	/* XXX XXX XXX */
2426		error = 0;
2427		goto out_locked;
2428	}
2429
2430	/*
2431	 * Zombies don't have a stack, so we can't read their psstrings.
2432	 * System processes also don't have a user stack.
2433	 */
2434	if (P_ZOMBIE(p) || (p->p_flag & P_SYSTEM) != 0) {
2435		error = EINVAL;
2436		goto out_locked;
2437	}
2438
2439	/*
2440	 * Lock the process down in memory.
2441	 */
2442	/* XXXCDC: how should locking work here? */
2443	if ((p->p_flag & P_WEXIT) || (p->p_vmspace->vm_refcnt < 1)) {
2444		error = EFAULT;
2445		goto out_locked;
2446	}
2447
2448	psstr_addr = (vaddr_t)p->p_psstr;
2449	if (type == KERN_PROC_ARGV || type == KERN_PROC_NARGV) {
2450		offsetn = p->p_psnargv;
2451		offsetv = p->p_psargv;
2452	} else {
2453		offsetn = p->p_psnenv;
2454		offsetv = p->p_psenv;
2455	}
2456	vmspace = p->p_vmspace;
2457	vmspace->vm_refcnt++;	/* XXX */
2458
2459	proclist_unlock_read();
2460
2461	/*
2462	 * Allocate a temporary buffer to hold the arguments.
2463	 */
2464	arg = malloc(PAGE_SIZE, M_TEMP, M_WAITOK);
2465
2466	/*
2467	 * Read in the ps_strings structure.
2468	 */
2469	aiov.iov_base = &pss;
2470	aiov.iov_len = sizeof(pss);
2471	auio.uio_iov = &aiov;
2472	auio.uio_iovcnt = 1;
2473	auio.uio_offset = psstr_addr;
2474	auio.uio_resid = sizeof(pss);
2475	auio.uio_rw = UIO_READ;
2476	UIO_SETUP_SYSSPACE(&auio);
2477	error = uvm_io(&vmspace->vm_map, &auio);
2478	if (error)
2479		goto done;
2480
2481	memcpy(&nargv, (char *)&pss + offsetn, sizeof(nargv));
2482	if (type == KERN_PROC_NARGV || type == KERN_PROC_NENV) {
2483		error = dcopyout(l, &nargv, oldp, sizeof(nargv));
2484		*oldlenp = sizeof(nargv);
2485		goto done;
2486	}
2487	/*
2488	 * Now read the address of the argument vector.
2489	 */
2490	switch (type) {
2491	case KERN_PROC_ARGV:
2492		/* FALLTHROUGH */
2493	case KERN_PROC_ENV:
2494		memcpy(&tmp, (char *)&pss + offsetv, sizeof(tmp));
2495		break;
2496	default:
2497		return (EINVAL);
2498	}
2499
2500#ifdef COMPAT_NETBSD32
2501	if (p->p_flag & P_32)
2502		len = sizeof(netbsd32_charp) * nargv;
2503	else
2504#endif
2505		len = sizeof(char *) * nargv;
2506
2507	argv = malloc(len, M_TEMP, M_WAITOK);
2508
2509	aiov.iov_base = argv;
2510	aiov.iov_len = len;
2511	auio.uio_iov = &aiov;
2512	auio.uio_iovcnt = 1;
2513	auio.uio_offset = (off_t)(unsigned long)tmp;
2514	auio.uio_resid = len;
2515	auio.uio_rw = UIO_READ;
2516	UIO_SETUP_SYSSPACE(&auio);
2517	error = uvm_io(&vmspace->vm_map, &auio);
2518	if (error)
2519		goto done;
2520
2521	/*
2522	 * Now copy each string.
2523	 */
2524	len = 0; /* bytes written to user buffer */
2525	for (i = 0; i < nargv; i++) {
2526		int finished = 0;
2527		vaddr_t base;
2528		size_t xlen;
2529		int j;
2530
2531#ifdef COMPAT_NETBSD32
2532		if (p->p_flag & P_32) {
2533			netbsd32_charp *argv32;
2534
2535			argv32 = (netbsd32_charp *)argv;
2536
2537			base = (vaddr_t)NETBSD32PTR64(argv32[i]);
2538		} else
2539#endif
2540			base = (vaddr_t)argv[i];
2541
2542		while (!finished) {
2543			xlen = PAGE_SIZE - (base & PAGE_MASK);
2544
2545			aiov.iov_base = arg;
2546			aiov.iov_len = PAGE_SIZE;
2547			auio.uio_iov = &aiov;
2548			auio.uio_iovcnt = 1;
2549			auio.uio_offset = base;
2550			auio.uio_resid = xlen;
2551			auio.uio_rw = UIO_READ;
2552			UIO_SETUP_SYSSPACE(&auio);
2553			error = uvm_io(&vmspace->vm_map, &auio);
2554			if (error)
2555				goto done;
2556
2557			/* Look for the end of the string */
2558			for (j = 0; j < xlen; j++) {
2559				if (arg[j] == '\0') {
2560					xlen = j + 1;
2561					finished = 1;
2562					break;
2563				}
2564			}
2565
2566			/* Check for user buffer overflow */
2567			if (len + xlen > *oldlenp) {
2568				finished = 1;
2569				if (len > *oldlenp)
2570					xlen = 0;
2571				else
2572					xlen = *oldlenp - len;
2573			}
2574
2575			/* Copyout the page */
2576			error = dcopyout(l, arg, (char *)oldp + len, xlen);
2577			if (error)
2578				goto done;
2579
2580			len += xlen;
2581			base += xlen;
2582		}
2583	}
2584	*oldlenp = len;
2585
2586done:
2587	if (argv != NULL)
2588		free(argv, M_TEMP);
2589
2590	uvmspace_free(vmspace);
2591
2592	free(arg, M_TEMP);
2593	return error;
2594
2595out_locked:
2596	proclist_unlock_read();
2597	return error;
2598}
2599
2600/*
2601 * Sysctl helper routine for Verified Exec.
2602 */
2603#if NVERIEXEC > 0
2604static int
2605sysctl_kern_veriexec(SYSCTLFN_ARGS)
2606{
2607	int newval, error;
2608	int *var = NULL, raise_only = 0;
2609	struct sysctlnode node;
2610
2611	node = *rnode;
2612
2613	switch (rnode->sysctl_num) {
2614	case VERIEXEC_STRICT:
2615		raise_only = 1;
2616		var = &veriexec_strict;
2617		break;
2618	case VERIEXEC_ALGORITHMS:
2619		node.sysctl_data = veriexec_fp_names;
2620		node.sysctl_size = strlen(veriexec_fp_names) + 1;
2621		return (sysctl_lookup(SYSCTLFN_CALL(&node)));
2622	default:
2623		return (EINVAL);
2624	}
2625
2626	newval = *var;
2627
2628	node.sysctl_data = &newval;
2629	error = sysctl_lookup(SYSCTLFN_CALL(&node));
2630	if (error || newp == NULL) {
2631		return (error);
2632	}
2633
2634	if (raise_only && (newval < *var))
2635		return (EPERM);
2636
2637	*var = newval;
2638
2639	return (error);
2640}
2641#endif /* NVERIEXEC > 0 */
2642
2643static int
2644sysctl_security_setidcore(SYSCTLFN_ARGS)
2645{
2646	int newsize, error;
2647	struct sysctlnode node;
2648
2649	node = *rnode;
2650	node.sysctl_data = &newsize;
2651	newsize = *(int *)rnode->sysctl_data;
2652	error = sysctl_lookup(SYSCTLFN_CALL(&node));
2653	if (error || newp == NULL)
2654		return error;
2655
2656	if (kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_SETIDCORE,
2657	    0, NULL, NULL, NULL))
2658		return (EPERM);
2659
2660	*(int *)rnode->sysctl_data = newsize;
2661
2662	return 0;
2663}
2664
2665static int
2666sysctl_security_setidcorename(SYSCTLFN_ARGS)
2667{
2668	int error;
2669	char *newsetidcorename;
2670	struct sysctlnode node;
2671
2672	newsetidcorename = PNBUF_GET();
2673	node = *rnode;
2674	node.sysctl_data = newsetidcorename;
2675	memcpy(node.sysctl_data, rnode->sysctl_data, MAXPATHLEN);
2676	error = sysctl_lookup(SYSCTLFN_CALL(&node));
2677	if (error || newp == NULL) {
2678		goto out;
2679	}
2680	if (kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_SETIDCORE,
2681	    0, NULL, NULL, NULL)) {
2682		error = EPERM;
2683		goto out;
2684	}
2685	if (strlen(newsetidcorename) == 0) {
2686		error = EINVAL;
2687		goto out;
2688	}
2689	memcpy(rnode->sysctl_data, node.sysctl_data, MAXPATHLEN);
2690out:
2691	PNBUF_PUT(newsetidcorename);
2692	return error;
2693}
2694
2695/*
2696 * sysctl helper routine for kern.cp_id node.  maps cpus to their
2697 * cpuids.
2698 */
2699static int
2700sysctl_kern_cpid(SYSCTLFN_ARGS)
2701{
2702	struct sysctlnode node = *rnode;
2703
2704#ifndef MULTIPROCESSOR
2705	uint64_t id;
2706
2707	if (namelen == 1) {
2708		if (name[0] != 0)
2709			return (ENOENT);
2710		/*
2711		 * you're allowed to ask for the zero'th processor
2712		 */
2713		name++;
2714		namelen--;
2715	}
2716	node.sysctl_data = &id;
2717	node.sysctl_size = sizeof(id);
2718	id = cpu_number();
2719	return (sysctl_lookup(SYSCTLFN_CALL(&node)));
2720
2721#else /* MULTIPROCESSOR */
2722	uint64_t *cp_id = NULL;
2723	int error, n = sysctl_ncpus();
2724	struct cpu_info *ci;
2725	CPU_INFO_ITERATOR cii;
2726
2727	/*
2728	 * here you may either retrieve a single cpu id or the whole
2729	 * set.  the size you get back when probing depends on what
2730	 * you ask for.
2731	 */
2732	switch (namelen) {
2733	case 0:
2734		node.sysctl_size = n * sizeof(uint64_t);
2735		n = -2; /* ALL */
2736		break;
2737	case 1:
2738		if (name[0] < 0 || name[0] >= n)
2739			return (ENOENT); /* ENOSUCHPROCESSOR */
2740		node.sysctl_size = sizeof(uint64_t);
2741		n = name[0];
2742		/*
2743		 * adjust these so that sysctl_lookup() will be happy
2744		 */
2745		name++;
2746		namelen--;
2747		break;
2748	default:
2749		return (EINVAL);
2750	}
2751
2752	cp_id = malloc(node.sysctl_size, M_TEMP, M_WAITOK|M_CANFAIL);
2753	if (cp_id == NULL)
2754		return (ENOMEM);
2755	node.sysctl_data = cp_id;
2756	memset(cp_id, 0, node.sysctl_size);
2757
2758	for (CPU_INFO_FOREACH(cii, ci)) {
2759		if (n <= 0)
2760			cp_id[0] = ci->ci_cpuid;
2761		/*
2762		 * if a specific processor was requested and we just
2763		 * did it, we're done here
2764		 */
2765		if (n == 0)
2766			break;
2767		/*
2768		 * if doing "all", skip to next cp_id slot for next processor
2769		 */
2770		if (n == -2)
2771			cp_id++;
2772		/*
2773		 * if we're doing a specific processor, we're one
2774		 * processor closer
2775		 */
2776		if (n > 0)
2777			n--;
2778	}
2779
2780	error = sysctl_lookup(SYSCTLFN_CALL(&node));
2781	free(node.sysctl_data, M_TEMP);
2782	return (error);
2783
2784#endif /* MULTIPROCESSOR */
2785}
2786
2787/*
2788 * sysctl helper routine for hw.usermem and hw.usermem64.  values are
2789 * calculate on the fly taking into account integer overflow and the
2790 * current wired count.
2791 */
2792static int
2793sysctl_hw_usermem(SYSCTLFN_ARGS)
2794{
2795	u_int ui;
2796	u_quad_t uq;
2797	struct sysctlnode node;
2798
2799	node = *rnode;
2800	switch (rnode->sysctl_num) {
2801	    case HW_USERMEM:
2802		if ((ui = physmem - uvmexp.wired) > (UINT_MAX / PAGE_SIZE))
2803			ui = UINT_MAX;
2804		else
2805			ui *= PAGE_SIZE;
2806		node.sysctl_data = &ui;
2807		break;
2808	case HW_USERMEM64:
2809		uq = (u_quad_t)(physmem - uvmexp.wired) * PAGE_SIZE;
2810		node.sysctl_data = &uq;
2811		break;
2812	default:
2813		return (EINVAL);
2814	}
2815
2816	return (sysctl_lookup(SYSCTLFN_CALL(&node)));
2817}
2818
2819/*
2820 * sysctl helper routine for kern.cnmagic node.  pulls the old value
2821 * out, encoded, and stuffs the new value in for decoding.
2822 */
2823static int
2824sysctl_hw_cnmagic(SYSCTLFN_ARGS)
2825{
2826	char magic[CNS_LEN];
2827	int error;
2828	struct sysctlnode node;
2829
2830	if (oldp)
2831		cn_get_magic(magic, CNS_LEN);
2832	node = *rnode;
2833	node.sysctl_data = &magic[0];
2834	error = sysctl_lookup(SYSCTLFN_CALL(&node));
2835	if (error || newp == NULL)
2836		return (error);
2837
2838	return (cn_set_magic(magic));
2839}
2840
2841static int
2842sysctl_hw_ncpu(SYSCTLFN_ARGS)
2843{
2844	int ncpu;
2845	struct sysctlnode node;
2846
2847	ncpu = sysctl_ncpus();
2848	node = *rnode;
2849	node.sysctl_data = &ncpu;
2850
2851	return (sysctl_lookup(SYSCTLFN_CALL(&node)));
2852}
2853
2854
2855/*
2856 * ********************************************************************
2857 * section 3: public helper routines that are used for more than one
2858 * node
2859 * ********************************************************************
2860 */
2861
2862/*
2863 * sysctl helper routine for the kern.root_device node and some ports'
2864 * machdep.root_device nodes.
2865 */
2866int
2867sysctl_root_device(SYSCTLFN_ARGS)
2868{
2869	struct sysctlnode node;
2870
2871	node = *rnode;
2872	node.sysctl_data = root_device->dv_xname;
2873	node.sysctl_size = strlen(root_device->dv_xname) + 1;
2874	return (sysctl_lookup(SYSCTLFN_CALL(&node)));
2875}
2876
2877/*
2878 * sysctl helper routine for kern.consdev, dependent on the current
2879 * state of the console.  also used for machdep.console_device on some
2880 * ports.
2881 */
2882int
2883sysctl_consdev(SYSCTLFN_ARGS)
2884{
2885	dev_t consdev;
2886	struct sysctlnode node;
2887
2888	if (cn_tab != NULL)
2889		consdev = cn_tab->cn_dev;
2890	else
2891		consdev = NODEV;
2892	node = *rnode;
2893	node.sysctl_data = &consdev;
2894	node.sysctl_size = sizeof(consdev);
2895	return (sysctl_lookup(SYSCTLFN_CALL(&node)));
2896}
2897
2898/*
2899 * ********************************************************************
2900 * section 4: support for some helpers
2901 * ********************************************************************
2902 */
2903
2904/*
2905 * Fill in a kinfo_proc2 structure for the specified process.
2906 */
2907static void
2908fill_kproc2(struct proc *p, struct kinfo_proc2 *ki)
2909{
2910	struct tty *tp;
2911	struct lwp *l;
2912	struct timeval ut, st;
2913
2914	memset(ki, 0, sizeof(*ki));
2915
2916	ki->p_paddr = PTRTOUINT64(p);
2917	ki->p_fd = PTRTOUINT64(p->p_fd);
2918	ki->p_cwdi = PTRTOUINT64(p->p_cwdi);
2919	ki->p_stats = PTRTOUINT64(p->p_stats);
2920	ki->p_limit = PTRTOUINT64(p->p_limit);
2921	ki->p_vmspace = PTRTOUINT64(p->p_vmspace);
2922	ki->p_sigacts = PTRTOUINT64(p->p_sigacts);
2923	ki->p_sess = PTRTOUINT64(p->p_session);
2924	ki->p_tsess = 0;	/* may be changed if controlling tty below */
2925	ki->p_ru = PTRTOUINT64(p->p_ru);
2926
2927	ki->p_eflag = 0;
2928	ki->p_exitsig = p->p_exitsig;
2929	ki->p_flag = p->p_flag;
2930
2931	ki->p_pid = p->p_pid;
2932	if (p->p_pptr)
2933		ki->p_ppid = p->p_pptr->p_pid;
2934	else
2935		ki->p_ppid = 0;
2936	ki->p_sid = p->p_session->s_sid;
2937	ki->p__pgid = p->p_pgrp->pg_id;
2938
2939	ki->p_tpgid = NO_PGID;	/* may be changed if controlling tty below */
2940
2941	ki->p_uid = kauth_cred_geteuid(p->p_cred);
2942	ki->p_ruid = kauth_cred_getuid(p->p_cred);
2943	ki->p_gid = kauth_cred_getegid(p->p_cred);
2944	ki->p_rgid = kauth_cred_getgid(p->p_cred);
2945	ki->p_svuid = kauth_cred_getsvuid(p->p_cred);
2946	ki->p_svgid = kauth_cred_getsvgid(p->p_cred);
2947
2948	ki->p_ngroups = kauth_cred_ngroups(p->p_cred);
2949	kauth_cred_getgroups(p->p_cred, ki->p_groups,
2950	    min(ki->p_ngroups, sizeof(ki->p_groups) / sizeof(ki->p_groups[0])));
2951
2952	ki->p_jobc = p->p_pgrp->pg_jobc;
2953	if ((p->p_flag & P_CONTROLT) && (tp = p->p_session->s_ttyp)) {
2954		ki->p_tdev = tp->t_dev;
2955		ki->p_tpgid = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PGID;
2956		ki->p_tsess = PTRTOUINT64(tp->t_session);
2957	} else {
2958		ki->p_tdev = NODEV;
2959	}
2960
2961	ki->p_estcpu = p->p_estcpu;
2962	ki->p_rtime_sec = p->p_rtime.tv_sec;
2963	ki->p_rtime_usec = p->p_rtime.tv_usec;
2964	ki->p_cpticks = p->p_cpticks;
2965	ki->p_pctcpu = p->p_pctcpu;
2966
2967	ki->p_uticks = p->p_uticks;
2968	ki->p_sticks = p->p_sticks;
2969	ki->p_iticks = p->p_iticks;
2970
2971	ki->p_tracep = PTRTOUINT64(p->p_tracep);
2972	ki->p_traceflag = p->p_traceflag;
2973
2974
2975	memcpy(&ki->p_siglist, &p->p_sigctx.ps_siglist, sizeof(ki_sigset_t));
2976	memcpy(&ki->p_sigmask, &p->p_sigctx.ps_sigmask, sizeof(ki_sigset_t));
2977	memcpy(&ki->p_sigignore, &p->p_sigctx.ps_sigignore,sizeof(ki_sigset_t));
2978	memcpy(&ki->p_sigcatch, &p->p_sigctx.ps_sigcatch, sizeof(ki_sigset_t));
2979
2980	ki->p_stat = p->p_stat; /* Will likely be overridden by LWP status */
2981	ki->p_realstat = p->p_stat;
2982	ki->p_nice = p->p_nice;
2983
2984	ki->p_xstat = p->p_xstat;
2985	ki->p_acflag = p->p_acflag;
2986
2987	strncpy(ki->p_comm, p->p_comm,
2988	    min(sizeof(ki->p_comm), sizeof(p->p_comm)));
2989
2990	strncpy(ki->p_login, p->p_session->s_login,
2991	    min(sizeof ki->p_login - 1, sizeof p->p_session->s_login));
2992
2993	strncpy(ki->p_ename, p->p_emul->e_name, sizeof(ki->p_ename));
2994	ki->p_ename[sizeof(ki->p_ename) - 1] = '\0';
2995
2996	ki->p_nlwps = p->p_nlwps;
2997	ki->p_nrlwps = p->p_nrlwps;
2998	ki->p_realflag = p->p_flag;
2999
3000	if (p->p_stat == SIDL || P_ZOMBIE(p)) {
3001		ki->p_vm_rssize = 0;
3002		ki->p_vm_tsize = 0;
3003		ki->p_vm_dsize = 0;
3004		ki->p_vm_ssize = 0;
3005		l = NULL;
3006	} else {
3007		struct vmspace *vm = p->p_vmspace;
3008
3009		ki->p_vm_rssize = vm_resident_count(vm);
3010		ki->p_vm_tsize = vm->vm_tsize;
3011		ki->p_vm_dsize = vm->vm_dsize;
3012		ki->p_vm_ssize = vm->vm_ssize;
3013
3014		/* Pick a "representative" LWP */
3015		l = proc_representative_lwp(p);
3016		ki->p_forw = PTRTOUINT64(l->l_forw);
3017		ki->p_back = PTRTOUINT64(l->l_back);
3018		ki->p_addr = PTRTOUINT64(l->l_addr);
3019		ki->p_stat = l->l_stat;
3020		ki->p_flag |= l->l_flag & P_SHARED;
3021		ki->p_swtime = l->l_swtime;
3022		ki->p_slptime = l->l_slptime;
3023		if (l->l_stat == LSONPROC) {
3024			KDASSERT(l->l_cpu != NULL);
3025			ki->p_schedflags = l->l_cpu->ci_schedstate.spc_flags;
3026		} else
3027			ki->p_schedflags = 0;
3028		ki->p_holdcnt = l->l_holdcnt;
3029		ki->p_priority = l->l_priority;
3030		ki->p_usrpri = l->l_usrpri;
3031		if (l->l_wmesg)
3032			strncpy(ki->p_wmesg, l->l_wmesg, sizeof(ki->p_wmesg));
3033		ki->p_wchan = PTRTOUINT64(l->l_wchan);
3034
3035	}
3036
3037	if (p->p_session->s_ttyvp)
3038		ki->p_eflag |= EPROC_CTTY;
3039	if (SESS_LEADER(p))
3040		ki->p_eflag |= EPROC_SLEADER;
3041
3042	/* XXX Is this double check necessary? */
3043	if (P_ZOMBIE(p)) {
3044		ki->p_uvalid = 0;
3045	} else {
3046		ki->p_uvalid = 1;
3047
3048		ki->p_ustart_sec = p->p_stats->p_start.tv_sec;
3049		ki->p_ustart_usec = p->p_stats->p_start.tv_usec;
3050
3051		calcru(p, &ut, &st, 0);
3052		ki->p_uutime_sec = ut.tv_sec;
3053		ki->p_uutime_usec = ut.tv_usec;
3054		ki->p_ustime_sec = st.tv_sec;
3055		ki->p_ustime_usec = st.tv_usec;
3056
3057		ki->p_uru_maxrss = p->p_stats->p_ru.ru_maxrss;
3058		ki->p_uru_ixrss = p->p_stats->p_ru.ru_ixrss;
3059		ki->p_uru_idrss = p->p_stats->p_ru.ru_idrss;
3060		ki->p_uru_isrss = p->p_stats->p_ru.ru_isrss;
3061		ki->p_uru_minflt = p->p_stats->p_ru.ru_minflt;
3062		ki->p_uru_majflt = p->p_stats->p_ru.ru_majflt;
3063		ki->p_uru_nswap = p->p_stats->p_ru.ru_nswap;
3064		ki->p_uru_inblock = p->p_stats->p_ru.ru_inblock;
3065		ki->p_uru_oublock = p->p_stats->p_ru.ru_oublock;
3066		ki->p_uru_msgsnd = p->p_stats->p_ru.ru_msgsnd;
3067		ki->p_uru_msgrcv = p->p_stats->p_ru.ru_msgrcv;
3068		ki->p_uru_nsignals = p->p_stats->p_ru.ru_nsignals;
3069		ki->p_uru_nvcsw = p->p_stats->p_ru.ru_nvcsw;
3070		ki->p_uru_nivcsw = p->p_stats->p_ru.ru_nivcsw;
3071
3072		timeradd(&p->p_stats->p_cru.ru_utime,
3073			 &p->p_stats->p_cru.ru_stime, &ut);
3074		ki->p_uctime_sec = ut.tv_sec;
3075		ki->p_uctime_usec = ut.tv_usec;
3076	}
3077#ifdef MULTIPROCESSOR
3078	if (l && l->l_cpu != NULL)
3079		ki->p_cpuid = l->l_cpu->ci_cpuid;
3080	else
3081#endif
3082		ki->p_cpuid = KI_NOCPU;
3083}
3084
3085/*
3086 * Fill in a kinfo_lwp structure for the specified lwp.
3087 */
3088static void
3089fill_lwp(struct lwp *l, struct kinfo_lwp *kl)
3090{
3091
3092	kl->l_forw = PTRTOUINT64(l->l_forw);
3093	kl->l_back = PTRTOUINT64(l->l_back);
3094	kl->l_laddr = PTRTOUINT64(l);
3095	kl->l_addr = PTRTOUINT64(l->l_addr);
3096	kl->l_stat = l->l_stat;
3097	kl->l_lid = l->l_lid;
3098	kl->l_flag = l->l_flag;
3099
3100	kl->l_swtime = l->l_swtime;
3101	kl->l_slptime = l->l_slptime;
3102	if (l->l_stat == LSONPROC) {
3103		KDASSERT(l->l_cpu != NULL);
3104		kl->l_schedflags = l->l_cpu->ci_schedstate.spc_flags;
3105	} else
3106		kl->l_schedflags = 0;
3107	kl->l_holdcnt = l->l_holdcnt;
3108	kl->l_priority = l->l_priority;
3109	kl->l_usrpri = l->l_usrpri;
3110	if (l->l_wmesg)
3111		strncpy(kl->l_wmesg, l->l_wmesg, sizeof(kl->l_wmesg));
3112	kl->l_wchan = PTRTOUINT64(l->l_wchan);
3113#ifdef MULTIPROCESSOR
3114	if (l->l_cpu != NULL)
3115		kl->l_cpuid = l->l_cpu->ci_cpuid;
3116	else
3117#endif
3118		kl->l_cpuid = KI_NOCPU;
3119}
3120
3121/*
3122 * Fill in an eproc structure for the specified process.
3123 */
3124void
3125fill_eproc(struct proc *p, struct eproc *ep)
3126{
3127	struct tty *tp;
3128	struct lwp *l;
3129
3130	ep->e_paddr = p;
3131	ep->e_sess = p->p_session;
3132	kauth_cred_topcred(p->p_cred, &ep->e_pcred);
3133	kauth_cred_toucred(p->p_cred, &ep->e_ucred);
3134	if (p->p_stat == SIDL || P_ZOMBIE(p)) {
3135		ep->e_vm.vm_rssize = 0;
3136		ep->e_vm.vm_tsize = 0;
3137		ep->e_vm.vm_dsize = 0;
3138		ep->e_vm.vm_ssize = 0;
3139		/* ep->e_vm.vm_pmap = XXX; */
3140	} else {
3141		struct vmspace *vm = p->p_vmspace;
3142
3143		ep->e_vm.vm_rssize = vm_resident_count(vm);
3144		ep->e_vm.vm_tsize = vm->vm_tsize;
3145		ep->e_vm.vm_dsize = vm->vm_dsize;
3146		ep->e_vm.vm_ssize = vm->vm_ssize;
3147
3148		/* Pick a "representative" LWP */
3149		l = proc_representative_lwp(p);
3150
3151		if (l->l_wmesg)
3152			strncpy(ep->e_wmesg, l->l_wmesg, WMESGLEN);
3153	}
3154	if (p->p_pptr)
3155		ep->e_ppid = p->p_pptr->p_pid;
3156	else
3157		ep->e_ppid = 0;
3158	ep->e_pgid = p->p_pgrp->pg_id;
3159	ep->e_sid = ep->e_sess->s_sid;
3160	ep->e_jobc = p->p_pgrp->pg_jobc;
3161	if ((p->p_flag & P_CONTROLT) &&
3162	    (tp = ep->e_sess->s_ttyp)) {
3163		ep->e_tdev = tp->t_dev;
3164		ep->e_tpgid = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PGID;
3165		ep->e_tsess = tp->t_session;
3166	} else
3167		ep->e_tdev = NODEV;
3168
3169	ep->e_xsize = ep->e_xrssize = 0;
3170	ep->e_xccount = ep->e_xswrss = 0;
3171	ep->e_flag = ep->e_sess->s_ttyvp ? EPROC_CTTY : 0;
3172	if (SESS_LEADER(p))
3173		ep->e_flag |= EPROC_SLEADER;
3174	strncpy(ep->e_login, ep->e_sess->s_login, MAXLOGNAME);
3175}
3176