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