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