xref: /openbsd-src/sys/kern/kern_sysctl.c (revision f6246b7f478ea7b2b6df549ae5998f8112d22650)
1 /*	$OpenBSD: kern_sysctl.c,v 1.385 2020/12/28 18:28:11 mglocker Exp $	*/
2 /*	$NetBSD: kern_sysctl.c,v 1.17 1996/05/20 17:49:05 mrg Exp $	*/
3 
4 /*-
5  * Copyright (c) 1982, 1986, 1989, 1993
6  *	The Regents of the University of California.  All rights reserved.
7  *
8  * This code is derived from software contributed to Berkeley by
9  * Mike Karels at Berkeley Software Design, Inc.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  * 3. Neither the name of the University nor the names of its contributors
20  *    may be used to endorse or promote products derived from this software
21  *    without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  *
35  *	@(#)kern_sysctl.c	8.4 (Berkeley) 4/14/94
36  */
37 
38 /*
39  * sysctl system call.
40  */
41 
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/kernel.h>
45 #include <sys/malloc.h>
46 #include <sys/pool.h>
47 #include <sys/proc.h>
48 #include <sys/resourcevar.h>
49 #include <sys/signalvar.h>
50 #include <sys/fcntl.h>
51 #include <sys/file.h>
52 #include <sys/filedesc.h>
53 #include <sys/vnode.h>
54 #include <sys/unistd.h>
55 #include <sys/buf.h>
56 #include <sys/ioctl.h>
57 #include <sys/tty.h>
58 #include <sys/disklabel.h>
59 #include <sys/disk.h>
60 #include <sys/sysctl.h>
61 #include <sys/msgbuf.h>
62 #include <sys/vmmeter.h>
63 #include <sys/namei.h>
64 #include <sys/exec.h>
65 #include <sys/mbuf.h>
66 #include <sys/percpu.h>
67 #include <sys/sensors.h>
68 #include <sys/pipe.h>
69 #include <sys/eventvar.h>
70 #include <sys/socketvar.h>
71 #include <sys/socket.h>
72 #include <sys/domain.h>
73 #include <sys/protosw.h>
74 #include <sys/pledge.h>
75 #include <sys/timetc.h>
76 #include <sys/evcount.h>
77 #include <sys/un.h>
78 #include <sys/unpcb.h>
79 #include <sys/sched.h>
80 #include <sys/mount.h>
81 #include <sys/syscallargs.h>
82 #include <sys/wait.h>
83 #include <sys/witness.h>
84 
85 #include <uvm/uvm_extern.h>
86 
87 #include <dev/cons.h>
88 
89 #include <net/route.h>
90 #include <netinet/in.h>
91 #include <netinet/ip.h>
92 #include <netinet/ip_var.h>
93 #include <netinet/in_pcb.h>
94 #include <netinet/ip6.h>
95 #include <netinet/tcp.h>
96 #include <netinet/tcp_timer.h>
97 #include <netinet/tcp_var.h>
98 #include <netinet/udp.h>
99 #include <netinet/udp_var.h>
100 #include <netinet6/ip6_var.h>
101 
102 #ifdef DDB
103 #include <ddb/db_var.h>
104 #endif
105 
106 #ifdef SYSVMSG
107 #include <sys/msg.h>
108 #endif
109 #ifdef SYSVSEM
110 #include <sys/sem.h>
111 #endif
112 #ifdef SYSVSHM
113 #include <sys/shm.h>
114 #endif
115 
116 #include "audio.h"
117 #include "video.h"
118 #include "pf.h"
119 
120 extern struct forkstat forkstat;
121 extern struct nchstats nchstats;
122 extern int nselcoll, fscale;
123 extern struct disklist_head disklist;
124 extern fixpt_t ccpu;
125 extern  long numvnodes;
126 #if NAUDIO > 0
127 extern int audio_record_enable;
128 #endif
129 #if NVIDEO > 0
130 extern int video_record_enable;
131 #endif
132 
133 int allowkmem;
134 int allowdt;
135 
136 int sysctl_diskinit(int, struct proc *);
137 int sysctl_proc_args(int *, u_int, void *, size_t *, struct proc *);
138 int sysctl_proc_cwd(int *, u_int, void *, size_t *, struct proc *);
139 int sysctl_proc_nobroadcastkill(int *, u_int, void *, size_t, void *, size_t *,
140 	struct proc *);
141 int sysctl_proc_vmmap(int *, u_int, void *, size_t *, struct proc *);
142 int sysctl_intrcnt(int *, u_int, void *, size_t *);
143 int sysctl_sensors(int *, u_int, void *, size_t *, void *, size_t);
144 int sysctl_cptime2(int *, u_int, void *, size_t *, void *, size_t);
145 #if NAUDIO > 0
146 int sysctl_audio(int *, u_int, void *, size_t *, void *, size_t);
147 #endif
148 #if NVIDEO > 0
149 int sysctl_video(int *, u_int, void *, size_t *, void *, size_t);
150 #endif
151 int sysctl_cpustats(int *, u_int, void *, size_t *, void *, size_t);
152 int sysctl_utc_offset(void *, size_t *, void *, size_t);
153 
154 void fill_file(struct kinfo_file *, struct file *, struct filedesc *, int,
155     struct vnode *, struct process *, struct proc *, struct socket *, int);
156 void fill_kproc(struct process *, struct kinfo_proc *, struct proc *, int);
157 
158 int (*cpu_cpuspeed)(int *);
159 
160 /*
161  * Lock to avoid too many processes vslocking a large amount of memory
162  * at the same time.
163  */
164 struct rwlock sysctl_lock = RWLOCK_INITIALIZER("sysctllk");
165 struct rwlock sysctl_disklock = RWLOCK_INITIALIZER("sysctldlk");
166 
167 int
168 sys_sysctl(struct proc *p, void *v, register_t *retval)
169 {
170 	struct sys_sysctl_args /* {
171 		syscallarg(const int *) name;
172 		syscallarg(u_int) namelen;
173 		syscallarg(void *) old;
174 		syscallarg(size_t *) oldlenp;
175 		syscallarg(void *) new;
176 		syscallarg(size_t) newlen;
177 	} */ *uap = v;
178 	int error, dolock = 1;
179 	size_t savelen = 0, oldlen = 0;
180 	sysctlfn *fn;
181 	int name[CTL_MAXNAME];
182 
183 	if (SCARG(uap, new) != NULL &&
184 	    (error = suser(p)))
185 		return (error);
186 	/*
187 	 * all top-level sysctl names are non-terminal
188 	 */
189 	if (SCARG(uap, namelen) > CTL_MAXNAME || SCARG(uap, namelen) < 2)
190 		return (EINVAL);
191 	error = copyin(SCARG(uap, name), name,
192 		       SCARG(uap, namelen) * sizeof(int));
193 	if (error)
194 		return (error);
195 
196 	error = pledge_sysctl(p, SCARG(uap, namelen),
197 	    name, SCARG(uap, new));
198 	if (error)
199 		return (error);
200 
201 	switch (name[0]) {
202 	case CTL_KERN:
203 		fn = kern_sysctl;
204 		break;
205 	case CTL_HW:
206 		fn = hw_sysctl;
207 		break;
208 	case CTL_VM:
209 		fn = uvm_sysctl;
210 		break;
211 	case CTL_NET:
212 		fn = net_sysctl;
213 		break;
214 	case CTL_FS:
215 		fn = fs_sysctl;
216 		break;
217 	case CTL_VFS:
218 		fn = vfs_sysctl;
219 		break;
220 	case CTL_MACHDEP:
221 		fn = cpu_sysctl;
222 		break;
223 #ifdef DEBUG_SYSCTL
224 	case CTL_DEBUG:
225 		fn = debug_sysctl;
226 		break;
227 #endif
228 #ifdef DDB
229 	case CTL_DDB:
230 		fn = ddb_sysctl;
231 		break;
232 #endif
233 	default:
234 		return (EOPNOTSUPP);
235 	}
236 
237 	if (SCARG(uap, oldlenp) &&
238 	    (error = copyin(SCARG(uap, oldlenp), &oldlen, sizeof(oldlen))))
239 		return (error);
240 	if (SCARG(uap, old) != NULL) {
241 		if ((error = rw_enter(&sysctl_lock, RW_WRITE|RW_INTR)) != 0)
242 			return (error);
243 		if (dolock) {
244 			if (atop(oldlen) > uvmexp.wiredmax - uvmexp.wired) {
245 				rw_exit_write(&sysctl_lock);
246 				return (ENOMEM);
247 			}
248 			error = uvm_vslock(p, SCARG(uap, old), oldlen,
249 			    PROT_READ | PROT_WRITE);
250 			if (error) {
251 				rw_exit_write(&sysctl_lock);
252 				return (error);
253 			}
254 		}
255 		savelen = oldlen;
256 	}
257 	error = (*fn)(&name[1], SCARG(uap, namelen) - 1, SCARG(uap, old),
258 	    &oldlen, SCARG(uap, new), SCARG(uap, newlen), p);
259 	if (SCARG(uap, old) != NULL) {
260 		if (dolock)
261 			uvm_vsunlock(p, SCARG(uap, old), savelen);
262 		rw_exit_write(&sysctl_lock);
263 	}
264 	if (error)
265 		return (error);
266 	if (SCARG(uap, oldlenp))
267 		error = copyout(&oldlen, SCARG(uap, oldlenp), sizeof(oldlen));
268 	return (error);
269 }
270 
271 /*
272  * Attributes stored in the kernel.
273  */
274 char hostname[MAXHOSTNAMELEN];
275 int hostnamelen;
276 char domainname[MAXHOSTNAMELEN];
277 int domainnamelen;
278 long hostid;
279 char *disknames = NULL;
280 size_t disknameslen;
281 struct diskstats *diskstats = NULL;
282 size_t diskstatslen;
283 int securelevel;
284 
285 /* morally const values reported by sysctl_bounded_arr */
286 static int arg_max = ARG_MAX;
287 static int openbsd = OpenBSD;
288 static int posix_version = _POSIX_VERSION;
289 static int ngroups_max = NGROUPS_MAX;
290 static int int_zero = 0;
291 static int int_one = 1;
292 static int maxpartitions = MAXPARTITIONS;
293 static int raw_part = RAW_PART;
294 
295 extern int somaxconn, sominconn;
296 extern int nosuidcoredump;
297 extern int maxlocksperuid;
298 extern int uvm_wxabort;
299 extern int global_ptrace;
300 
301 const struct sysctl_bounded_args kern_vars[] = {
302 	{KERN_OSREV, &openbsd, 1, 0},
303 	{KERN_MAXVNODES, &maxvnodes, 0, INT_MAX},
304 	{KERN_MAXPROC, &maxprocess, 0, INT_MAX},
305 	{KERN_MAXFILES, &maxfiles, 0, INT_MAX},
306 	{KERN_NFILES, &numfiles, 1, 0},
307 	{KERN_TTYCOUNT, &tty_count, 1, 0},
308 	{KERN_ARGMAX, &arg_max, 1, 0},
309 	{KERN_NSELCOLL, &nselcoll, 1, 0},
310 	{KERN_POSIX1, &posix_version, 1, 0},
311 	{KERN_NGROUPS, &ngroups_max, 1, 0},
312 	{KERN_JOB_CONTROL, &int_one, 1, 0},
313 	{KERN_SAVED_IDS, &int_one, 1, 0},
314 	{KERN_MAXPARTITIONS, &maxpartitions, 1, 0},
315 	{KERN_RAWPARTITION, &raw_part, 1, 0},
316 	{KERN_MAXTHREAD, &maxthread, 0, INT_MAX},
317 	{KERN_NTHREADS, &nthreads, 1, 0},
318 	{KERN_SOMAXCONN, &somaxconn, 0, SHRT_MAX},
319 	{KERN_SOMINCONN, &sominconn, 0, SHRT_MAX},
320 	{KERN_NOSUIDCOREDUMP, &nosuidcoredump, 0, 3},
321 	{KERN_FSYNC, &int_one, 1, 0},
322 	{KERN_SYSVMSG,
323 #ifdef SYSVMSG
324 	 &int_one,
325 #else
326 	 &int_zero,
327 #endif
328 	 1, 0},
329 	{KERN_SYSVSEM,
330 #ifdef SYSVSEM
331 	 &int_one,
332 #else
333 	 &int_zero,
334 #endif
335 	 1, 0},
336 	{KERN_SYSVSHM,
337 #ifdef SYSVSHM
338 	 &int_one,
339 #else
340 	 &int_zero,
341 #endif
342 	 1, 0},
343 	{KERN_FSCALE, &fscale, 1, 0},
344 	{KERN_CCPU, &ccpu, 1, 0},
345 	{KERN_NPROCS, &nprocesses, 1, 0},
346 	{KERN_SPLASSERT, &splassert_ctl, 0, 3},
347 	{KERN_MAXLOCKSPERUID, &maxlocksperuid, 0, INT_MAX},
348 	{KERN_WXABORT, &uvm_wxabort, 0, 1},
349 	{KERN_NETLIVELOCKS, &int_zero, 1, 0},
350 #ifdef PTRACE
351 	{KERN_GLOBAL_PTRACE, &global_ptrace, 0, 1},
352 #endif
353 };
354 
355 /*
356  * kernel related system variables.
357  */
358 int
359 kern_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
360     size_t newlen, struct proc *p)
361 {
362 	int error, level, inthostid, stackgap;
363 	dev_t dev;
364 	extern int pool_debug;
365 
366 	/* all sysctl names at this level are terminal except a ton of them */
367 	if (namelen != 1) {
368 		switch (name[0]) {
369 		case KERN_PROC:
370 		case KERN_PROF:
371 		case KERN_MALLOCSTATS:
372 		case KERN_TTY:
373 		case KERN_POOL:
374 		case KERN_PROC_ARGS:
375 		case KERN_PROC_CWD:
376 		case KERN_PROC_NOBROADCASTKILL:
377 		case KERN_PROC_VMMAP:
378 		case KERN_SYSVIPC_INFO:
379 		case KERN_SEMINFO:
380 		case KERN_SHMINFO:
381 		case KERN_INTRCNT:
382 		case KERN_WATCHDOG:
383 		case KERN_EVCOUNT:
384 		case KERN_TIMECOUNTER:
385 		case KERN_CPTIME2:
386 		case KERN_FILE:
387 		case KERN_WITNESS:
388 		case KERN_AUDIO:
389 		case KERN_VIDEO:
390 		case KERN_CPUSTATS:
391 			break;
392 		default:
393 			return (ENOTDIR);	/* overloaded */
394 		}
395 	}
396 
397 	switch (name[0]) {
398 	case KERN_OSTYPE:
399 		return (sysctl_rdstring(oldp, oldlenp, newp, ostype));
400 	case KERN_OSRELEASE:
401 		return (sysctl_rdstring(oldp, oldlenp, newp, osrelease));
402 	case KERN_OSVERSION:
403 		return (sysctl_rdstring(oldp, oldlenp, newp, osversion));
404 	case KERN_VERSION:
405 		return (sysctl_rdstring(oldp, oldlenp, newp, version));
406 	case KERN_NUMVNODES:  /* XXX numvnodes is a long */
407 		return (sysctl_rdint(oldp, oldlenp, newp, numvnodes));
408 	case KERN_SECURELVL:
409 		level = securelevel;
410 		if ((error = sysctl_int(oldp, oldlenp, newp, newlen, &level)) ||
411 		    newp == NULL)
412 			return (error);
413 		if ((securelevel > 0 || level < -1) &&
414 		    level < securelevel && p->p_p->ps_pid != 1)
415 			return (EPERM);
416 		securelevel = level;
417 		return (0);
418 	case KERN_ALLOWDT:
419 		if (securelevel > 0)
420 			return (sysctl_rdint(oldp, oldlenp, newp, allowdt));
421 		return (sysctl_int(oldp, oldlenp, newp, newlen,  &allowdt));
422 	case KERN_ALLOWKMEM:
423 		if (securelevel > 0)
424 			return (sysctl_rdint(oldp, oldlenp, newp, allowkmem));
425 		return (sysctl_int(oldp, oldlenp, newp, newlen, &allowkmem));
426 	case KERN_HOSTNAME:
427 		error = sysctl_tstring(oldp, oldlenp, newp, newlen,
428 		    hostname, sizeof(hostname));
429 		if (newp && !error)
430 			hostnamelen = newlen;
431 		return (error);
432 	case KERN_DOMAINNAME:
433 		error = sysctl_tstring(oldp, oldlenp, newp, newlen,
434 		    domainname, sizeof(domainname));
435 		if (newp && !error)
436 			domainnamelen = newlen;
437 		return (error);
438 	case KERN_HOSTID:
439 		inthostid = hostid;  /* XXX assumes sizeof long <= sizeof int */
440 		error =  sysctl_int(oldp, oldlenp, newp, newlen, &inthostid);
441 		hostid = inthostid;
442 		return (error);
443 	case KERN_CLOCKRATE:
444 		return (sysctl_clockrate(oldp, oldlenp, newp));
445 	case KERN_BOOTTIME: {
446 		struct timeval bt;
447 		memset(&bt, 0, sizeof bt);
448 		microboottime(&bt);
449 		return (sysctl_rdstruct(oldp, oldlenp, newp, &bt, sizeof bt));
450 	  }
451 #ifndef SMALL_KERNEL
452 	case KERN_PROC:
453 		return (sysctl_doproc(name + 1, namelen - 1, oldp, oldlenp));
454 	case KERN_PROC_ARGS:
455 		return (sysctl_proc_args(name + 1, namelen - 1, oldp, oldlenp,
456 		     p));
457 	case KERN_PROC_CWD:
458 		return (sysctl_proc_cwd(name + 1, namelen - 1, oldp, oldlenp,
459 		     p));
460 	case KERN_PROC_NOBROADCASTKILL:
461 		return (sysctl_proc_nobroadcastkill(name + 1, namelen - 1,
462 		     newp, newlen, oldp, oldlenp, p));
463 	case KERN_PROC_VMMAP:
464 		return (sysctl_proc_vmmap(name + 1, namelen - 1, oldp, oldlenp,
465 		     p));
466 	case KERN_FILE:
467 		return (sysctl_file(name + 1, namelen - 1, oldp, oldlenp, p));
468 #endif
469 	case KERN_MBSTAT: {
470 		extern struct cpumem *mbstat;
471 		uint64_t counters[MBSTAT_COUNT];
472 		struct mbstat mbs;
473 		unsigned int i;
474 
475 		memset(&mbs, 0, sizeof(mbs));
476 		counters_read(mbstat, counters, MBSTAT_COUNT);
477 		for (i = 0; i < MBSTAT_TYPES; i++)
478 			mbs.m_mtypes[i] = counters[i];
479 
480 		mbs.m_drops = counters[MBSTAT_DROPS];
481 		mbs.m_wait = counters[MBSTAT_WAIT];
482 		mbs.m_drain = counters[MBSTAT_DRAIN];
483 
484 		return (sysctl_rdstruct(oldp, oldlenp, newp,
485 		    &mbs, sizeof(mbs)));
486 	}
487 #if defined(GPROF) || defined(DDBPROF)
488 	case KERN_PROF:
489 		return (sysctl_doprof(name + 1, namelen - 1, oldp, oldlenp,
490 		    newp, newlen));
491 #endif
492 	case KERN_MSGBUFSIZE:
493 	case KERN_CONSBUFSIZE: {
494 		struct msgbuf *mp;
495 		mp = (name[0] == KERN_MSGBUFSIZE) ? msgbufp : consbufp;
496 		/*
497 		 * deal with cases where the message buffer has
498 		 * become corrupted.
499 		 */
500 		if (!mp || mp->msg_magic != MSG_MAGIC)
501 			return (ENXIO);
502 		return (sysctl_rdint(oldp, oldlenp, newp, mp->msg_bufs));
503 	}
504 	case KERN_CONSBUF:
505 		if ((error = suser(p)))
506 			return (error);
507 		/* FALLTHROUGH */
508 	case KERN_MSGBUF: {
509 		struct msgbuf *mp;
510 		mp = (name[0] == KERN_MSGBUF) ? msgbufp : consbufp;
511 		/* see note above */
512 		if (!mp || mp->msg_magic != MSG_MAGIC)
513 			return (ENXIO);
514 		return (sysctl_rdstruct(oldp, oldlenp, newp, mp,
515 		    mp->msg_bufs + offsetof(struct msgbuf, msg_bufc)));
516 	}
517 	case KERN_MALLOCSTATS:
518 		return (sysctl_malloc(name + 1, namelen - 1, oldp, oldlenp,
519 		    newp, newlen, p));
520 	case KERN_CPTIME:
521 	{
522 		CPU_INFO_ITERATOR cii;
523 		struct cpu_info *ci;
524 		long cp_time[CPUSTATES];
525 		int i, n = 0;
526 
527 		memset(cp_time, 0, sizeof(cp_time));
528 
529 		CPU_INFO_FOREACH(cii, ci) {
530 			if (!cpu_is_online(ci))
531 				continue;
532 			n++;
533 			for (i = 0; i < CPUSTATES; i++)
534 				cp_time[i] += ci->ci_schedstate.spc_cp_time[i];
535 		}
536 
537 		for (i = 0; i < CPUSTATES; i++)
538 			cp_time[i] /= n;
539 
540 		return (sysctl_rdstruct(oldp, oldlenp, newp, &cp_time,
541 		    sizeof(cp_time)));
542 	}
543 	case KERN_NCHSTATS:
544 		return (sysctl_rdstruct(oldp, oldlenp, newp, &nchstats,
545 		    sizeof(struct nchstats)));
546 	case KERN_FORKSTAT:
547 		return (sysctl_rdstruct(oldp, oldlenp, newp, &forkstat,
548 		    sizeof(struct forkstat)));
549 	case KERN_TTY:
550 		return (sysctl_tty(name + 1, namelen - 1, oldp, oldlenp,
551 		    newp, newlen));
552 	case KERN_POOL:
553 		return (sysctl_dopool(name + 1, namelen - 1, oldp, oldlenp));
554 	case KERN_STACKGAPRANDOM:
555 		stackgap = stackgap_random;
556 		error = sysctl_int(oldp, oldlenp, newp, newlen, &stackgap);
557 		if (error)
558 			return (error);
559 		/*
560 		 * Safety harness.
561 		 */
562 		if ((stackgap < ALIGNBYTES && stackgap != 0) ||
563 		    !powerof2(stackgap) || stackgap >= MAXSSIZ)
564 			return (EINVAL);
565 		stackgap_random = stackgap;
566 		return (0);
567 #if defined(SYSVMSG) || defined(SYSVSEM) || defined(SYSVSHM)
568 	case KERN_SYSVIPC_INFO:
569 		return (sysctl_sysvipc(name + 1, namelen - 1, oldp, oldlenp));
570 #endif
571 #ifdef SYSVSEM
572 	case KERN_SEMINFO:
573 		return (sysctl_sysvsem(name + 1, namelen - 1, oldp, oldlenp,
574 		    newp, newlen));
575 #endif
576 #ifdef SYSVSHM
577 	case KERN_SHMINFO:
578 		return (sysctl_sysvshm(name + 1, namelen - 1, oldp, oldlenp,
579 		    newp, newlen));
580 #endif
581 #ifndef SMALL_KERNEL
582 	case KERN_INTRCNT:
583 		return (sysctl_intrcnt(name + 1, namelen - 1, oldp, oldlenp));
584 	case KERN_WATCHDOG:
585 		return (sysctl_wdog(name + 1, namelen - 1, oldp, oldlenp,
586 		    newp, newlen));
587 #endif
588 	case KERN_MAXCLUSTERS: {
589 		int val = nmbclust;
590 		error = sysctl_int(oldp, oldlenp, newp, newlen, &val);
591 		if (error == 0 && val != nmbclust)
592 			error = nmbclust_update(val);
593 		return (error);
594 	}
595 #ifndef SMALL_KERNEL
596 	case KERN_EVCOUNT:
597 		return (evcount_sysctl(name + 1, namelen - 1, oldp, oldlenp,
598 		    newp, newlen));
599 #endif
600 	case KERN_TIMECOUNTER:
601 		return (sysctl_tc(name + 1, namelen - 1, oldp, oldlenp,
602 		    newp, newlen));
603 	case KERN_CPTIME2:
604 		return (sysctl_cptime2(name + 1, namelen -1, oldp, oldlenp,
605 		    newp, newlen));
606 	case KERN_CACHEPCT: {
607 		u_int64_t dmapages;
608 		int opct, pgs;
609 		opct = bufcachepercent;
610 		error = sysctl_int(oldp, oldlenp, newp, newlen,
611 		    &bufcachepercent);
612 		if (error)
613 			return(error);
614 		if (bufcachepercent > 90 || bufcachepercent < 5) {
615 			bufcachepercent = opct;
616 			return (EINVAL);
617 		}
618 		dmapages = uvm_pagecount(&dma_constraint);
619 		if (bufcachepercent != opct) {
620 			pgs = bufcachepercent * dmapages / 100;
621 			bufadjust(pgs); /* adjust bufpages */
622 			bufhighpages = bufpages; /* set high water mark */
623 		}
624 		return(0);
625 	}
626 	case KERN_CONSDEV:
627 		if (cn_tab != NULL)
628 			dev = cn_tab->cn_dev;
629 		else
630 			dev = NODEV;
631 		return sysctl_rdstruct(oldp, oldlenp, newp, &dev, sizeof(dev));
632 	case KERN_POOL_DEBUG: {
633 		int old_pool_debug = pool_debug;
634 
635 		error = sysctl_int(oldp, oldlenp, newp, newlen,
636 		    &pool_debug);
637 		if (error == 0 && pool_debug != old_pool_debug)
638 			pool_reclaim_all();
639 		return (error);
640 	}
641 #ifdef WITNESS
642 	case KERN_WITNESSWATCH:
643 		return witness_sysctl_watch(oldp, oldlenp, newp, newlen);
644 	case KERN_WITNESS:
645 		return witness_sysctl(name + 1, namelen - 1, oldp, oldlenp,
646 		    newp, newlen);
647 #endif
648 #if NAUDIO > 0
649 	case KERN_AUDIO:
650 		return (sysctl_audio(name + 1, namelen - 1, oldp, oldlenp,
651 		    newp, newlen));
652 #endif
653 #if NVIDEO > 0
654 	case KERN_VIDEO:
655 		return (sysctl_video(name + 1, namelen - 1, oldp, oldlenp,
656 		    newp, newlen));
657 #endif
658 	case KERN_CPUSTATS:
659 		return (sysctl_cpustats(name + 1, namelen - 1, oldp, oldlenp,
660 		    newp, newlen));
661 #if NPF > 0
662 	case KERN_PFSTATUS:
663 		return (pf_sysctl(oldp, oldlenp, newp, newlen));
664 #endif
665 	case KERN_TIMEOUT_STATS:
666 		return (timeout_sysctl(oldp, oldlenp, newp, newlen));
667 	case KERN_UTC_OFFSET:
668 		return (sysctl_utc_offset(oldp, oldlenp, newp, newlen));
669 	default:
670 		return (sysctl_bounded_arr(kern_vars, nitems(kern_vars), name,
671 		    namelen, oldp, oldlenp, newp, newlen));
672 	}
673 	/* NOTREACHED */
674 }
675 
676 /*
677  * hardware related system variables.
678  */
679 char *hw_vendor, *hw_prod, *hw_uuid, *hw_serial, *hw_ver;
680 int allowpowerdown = 1;
681 
682 /* morally const values reported by sysctl_bounded_arr */
683 static int byte_order = BYTE_ORDER;
684 static int page_size = PAGE_SIZE;
685 
686 const struct sysctl_bounded_args hw_vars[] = {
687 	{HW_NCPU, &ncpus, 1, 0},
688 	{HW_NCPUFOUND, &ncpusfound, 1, 0},
689 	{HW_BYTEORDER, &byte_order, 1, 0},
690 	{HW_PAGESIZE, &page_size, 1, 0},
691 	{HW_DISKCOUNT, &disk_count, 1, 0},
692 };
693 
694 int
695 hw_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
696     size_t newlen, struct proc *p)
697 {
698 	extern char machine[], cpu_model[];
699 	int err, cpuspeed;
700 
701 	/* all sysctl names at this level except sensors are terminal */
702 	if (name[0] != HW_SENSORS && namelen != 1)
703 		return (ENOTDIR);		/* overloaded */
704 
705 	switch (name[0]) {
706 	case HW_MACHINE:
707 		return (sysctl_rdstring(oldp, oldlenp, newp, machine));
708 	case HW_MODEL:
709 		return (sysctl_rdstring(oldp, oldlenp, newp, cpu_model));
710 	case HW_NCPUONLINE:
711 		return (sysctl_rdint(oldp, oldlenp, newp,
712 		    sysctl_hwncpuonline()));
713 	case HW_PHYSMEM:
714 		return (sysctl_rdint(oldp, oldlenp, newp, ptoa(physmem)));
715 	case HW_USERMEM:
716 		return (sysctl_rdint(oldp, oldlenp, newp,
717 		    ptoa(physmem - uvmexp.wired)));
718 	case HW_DISKNAMES:
719 		err = sysctl_diskinit(0, p);
720 		if (err)
721 			return err;
722 		if (disknames)
723 			return (sysctl_rdstring(oldp, oldlenp, newp,
724 			    disknames));
725 		else
726 			return (sysctl_rdstring(oldp, oldlenp, newp, ""));
727 	case HW_DISKSTATS:
728 		err = sysctl_diskinit(1, p);
729 		if (err)
730 			return err;
731 		return (sysctl_rdstruct(oldp, oldlenp, newp, diskstats,
732 		    disk_count * sizeof(struct diskstats)));
733 	case HW_CPUSPEED:
734 		if (!cpu_cpuspeed)
735 			return (EOPNOTSUPP);
736 		err = cpu_cpuspeed(&cpuspeed);
737 		if (err)
738 			return err;
739 		return (sysctl_rdint(oldp, oldlenp, newp, cpuspeed));
740 #ifndef	SMALL_KERNEL
741 	case HW_SENSORS:
742 		return (sysctl_sensors(name + 1, namelen - 1, oldp, oldlenp,
743 		    newp, newlen));
744 	case HW_SETPERF:
745 		return (sysctl_hwsetperf(oldp, oldlenp, newp, newlen));
746 	case HW_PERFPOLICY:
747 		return (sysctl_hwperfpolicy(oldp, oldlenp, newp, newlen));
748 #endif /* !SMALL_KERNEL */
749 	case HW_VENDOR:
750 		if (hw_vendor)
751 			return (sysctl_rdstring(oldp, oldlenp, newp,
752 			    hw_vendor));
753 		else
754 			return (EOPNOTSUPP);
755 	case HW_PRODUCT:
756 		if (hw_prod)
757 			return (sysctl_rdstring(oldp, oldlenp, newp, hw_prod));
758 		else
759 			return (EOPNOTSUPP);
760 	case HW_VERSION:
761 		if (hw_ver)
762 			return (sysctl_rdstring(oldp, oldlenp, newp, hw_ver));
763 		else
764 			return (EOPNOTSUPP);
765 	case HW_SERIALNO:
766 		if (hw_serial)
767 			return (sysctl_rdstring(oldp, oldlenp, newp,
768 			    hw_serial));
769 		else
770 			return (EOPNOTSUPP);
771 	case HW_UUID:
772 		if (hw_uuid)
773 			return (sysctl_rdstring(oldp, oldlenp, newp, hw_uuid));
774 		else
775 			return (EOPNOTSUPP);
776 	case HW_PHYSMEM64:
777 		return (sysctl_rdquad(oldp, oldlenp, newp,
778 		    ptoa((psize_t)physmem)));
779 	case HW_USERMEM64:
780 		return (sysctl_rdquad(oldp, oldlenp, newp,
781 		    ptoa((psize_t)physmem - uvmexp.wired)));
782 	case HW_ALLOWPOWERDOWN:
783 		if (securelevel > 0)
784 			return (sysctl_rdint(oldp, oldlenp, newp,
785 			    allowpowerdown));
786 		return (sysctl_int(oldp, oldlenp, newp, newlen,
787 		    &allowpowerdown));
788 #ifdef __HAVE_CPU_TOPOLOGY
789 	case HW_SMT:
790 		return (sysctl_hwsmt(oldp, oldlenp, newp, newlen));
791 #endif
792 	default:
793 		return sysctl_bounded_arr(hw_vars, nitems(hw_vars), name,
794 		    namelen, oldp, oldlenp, newp, newlen);
795 	}
796 	/* NOTREACHED */
797 }
798 
799 #ifdef DEBUG_SYSCTL
800 /*
801  * Debugging related system variables.
802  */
803 extern struct ctldebug debug_vfs_busyprt;
804 struct ctldebug debug1, debug2, debug3, debug4;
805 struct ctldebug debug5, debug6, debug7, debug8, debug9;
806 struct ctldebug debug10, debug11, debug12, debug13, debug14;
807 struct ctldebug debug15, debug16, debug17, debug18, debug19;
808 static struct ctldebug *debugvars[CTL_DEBUG_MAXID] = {
809 	&debug_vfs_busyprt,
810 	&debug1, &debug2, &debug3, &debug4,
811 	&debug5, &debug6, &debug7, &debug8, &debug9,
812 	&debug10, &debug11, &debug12, &debug13, &debug14,
813 	&debug15, &debug16, &debug17, &debug18, &debug19,
814 };
815 int
816 debug_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
817     size_t newlen, struct proc *p)
818 {
819 	struct ctldebug *cdp;
820 
821 	/* all sysctl names at this level are name and field */
822 	if (namelen != 2)
823 		return (ENOTDIR);		/* overloaded */
824 	if (name[0] < 0 || name[0] >= nitems(debugvars))
825 		return (EOPNOTSUPP);
826 	cdp = debugvars[name[0]];
827 	if (cdp->debugname == 0)
828 		return (EOPNOTSUPP);
829 	switch (name[1]) {
830 	case CTL_DEBUG_NAME:
831 		return (sysctl_rdstring(oldp, oldlenp, newp, cdp->debugname));
832 	case CTL_DEBUG_VALUE:
833 		return (sysctl_int(oldp, oldlenp, newp, newlen, cdp->debugvar));
834 	default:
835 		return (EOPNOTSUPP);
836 	}
837 	/* NOTREACHED */
838 }
839 #endif /* DEBUG_SYSCTL */
840 
841 /*
842  * Reads, or writes that lower the value
843  */
844 int
845 sysctl_int_lower(void *oldp, size_t *oldlenp, void *newp, size_t newlen, int *valp)
846 {
847 	unsigned int oval = *valp, val = *valp;
848 	int error;
849 
850 	if (newp == NULL)
851 		return (sysctl_rdint(oldp, oldlenp, newp, *valp));
852 
853 	if ((error = sysctl_int(oldp, oldlenp, newp, newlen, &val)))
854 		return (error);
855 	if (val > oval)
856 		return (EPERM);		/* do not allow raising */
857 	*(unsigned int *)valp = val;
858 	return (0);
859 }
860 
861 /*
862  * Validate parameters and get old / set new parameters
863  * for an integer-valued sysctl function.
864  */
865 int
866 sysctl_int(void *oldp, size_t *oldlenp, void *newp, size_t newlen, int *valp)
867 {
868 	return (sysctl_int_bounded(oldp, oldlenp, newp, newlen, valp, 0, 0));
869 }
870 
871 int
872 sysctl_int_bounded(void *oldp, size_t *oldlenp, void *newp, size_t newlen,
873     int *valp, int minimum, int maximum)
874 {
875 	int error = 0;
876 	int val;
877 
878 	if (oldp && *oldlenp < sizeof(int))
879 		return (ENOMEM);
880 	if (newp && newlen != sizeof(int))
881 		return (EINVAL);
882 	*oldlenp = sizeof(int);
883 	val = *valp;
884 	if (oldp)
885 		error = copyout(&val, oldp, sizeof(int));
886 	if (error == 0 && newp)
887 		error = copyin(newp, &val, sizeof(int));
888 	if (error)
889 		return (error);
890 	if (minimum == maximum || (minimum <= val && val <= maximum))
891 		*valp = val;
892 	else
893 		error = EINVAL;
894 	return (error);
895 }
896 
897 /*
898  * As above, but read-only.
899  */
900 int
901 sysctl_rdint(void *oldp, size_t *oldlenp, void *newp, int val)
902 {
903 	int error = 0;
904 
905 	if (oldp && *oldlenp < sizeof(int))
906 		return (ENOMEM);
907 	if (newp)
908 		return (EPERM);
909 	*oldlenp = sizeof(int);
910 	if (oldp)
911 		error = copyout((caddr_t)&val, oldp, sizeof(int));
912 	return (error);
913 }
914 
915 /*
916  * Array of bounded integer values.
917  */
918 int
919 sysctl_bounded_arr(const struct sysctl_bounded_args *valpp, u_int valplen,
920     int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
921     size_t newlen)
922 {
923 	u_int i;
924 	if (namelen != 1)
925 		return (ENOTDIR);
926 	for (i = 0; i < valplen; ++i) {
927 		if (valpp[i].mib == name[0]) {
928 			if (valpp[i].minimum <= valpp[i].maximum) {
929 				return (sysctl_int_bounded(oldp, oldlenp, newp,
930 				    newlen, valpp[i].var, valpp[i].minimum,
931 				    valpp[i].maximum));
932 			} else {
933 				return (sysctl_rdint(oldp, oldlenp, newp,
934 				    *valpp[i].var));
935 			}
936 		}
937 	}
938 	return (EOPNOTSUPP);
939 }
940 
941 /*
942  * Validate parameters and get old / set new parameters
943  * for an integer-valued sysctl function.
944  */
945 int
946 sysctl_quad(void *oldp, size_t *oldlenp, void *newp, size_t newlen,
947     int64_t *valp)
948 {
949 	int error = 0;
950 
951 	if (oldp && *oldlenp < sizeof(int64_t))
952 		return (ENOMEM);
953 	if (newp && newlen != sizeof(int64_t))
954 		return (EINVAL);
955 	*oldlenp = sizeof(int64_t);
956 	if (oldp)
957 		error = copyout(valp, oldp, sizeof(int64_t));
958 	if (error == 0 && newp)
959 		error = copyin(newp, valp, sizeof(int64_t));
960 	return (error);
961 }
962 
963 /*
964  * As above, but read-only.
965  */
966 int
967 sysctl_rdquad(void *oldp, size_t *oldlenp, void *newp, int64_t val)
968 {
969 	int error = 0;
970 
971 	if (oldp && *oldlenp < sizeof(int64_t))
972 		return (ENOMEM);
973 	if (newp)
974 		return (EPERM);
975 	*oldlenp = sizeof(int64_t);
976 	if (oldp)
977 		error = copyout((caddr_t)&val, oldp, sizeof(int64_t));
978 	return (error);
979 }
980 
981 /*
982  * Validate parameters and get old / set new parameters
983  * for a string-valued sysctl function.
984  */
985 int
986 sysctl_string(void *oldp, size_t *oldlenp, void *newp, size_t newlen, char *str,
987     size_t maxlen)
988 {
989 	return sysctl__string(oldp, oldlenp, newp, newlen, str, maxlen, 0);
990 }
991 
992 int
993 sysctl_tstring(void *oldp, size_t *oldlenp, void *newp, size_t newlen,
994     char *str, size_t maxlen)
995 {
996 	return sysctl__string(oldp, oldlenp, newp, newlen, str, maxlen, 1);
997 }
998 
999 int
1000 sysctl__string(void *oldp, size_t *oldlenp, void *newp, size_t newlen,
1001     char *str, size_t maxlen, int trunc)
1002 {
1003 	size_t len;
1004 	int error = 0;
1005 
1006 	len = strlen(str) + 1;
1007 	if (oldp && *oldlenp < len) {
1008 		if (trunc == 0 || *oldlenp == 0)
1009 			return (ENOMEM);
1010 	}
1011 	if (newp && newlen >= maxlen)
1012 		return (EINVAL);
1013 	if (oldp) {
1014 		if (trunc && *oldlenp < len) {
1015 			len = *oldlenp;
1016 			error = copyout(str, oldp, len - 1);
1017 			if (error == 0)
1018 				error = copyout("", (char *)oldp + len - 1, 1);
1019 		} else {
1020 			error = copyout(str, oldp, len);
1021 		}
1022 	}
1023 	*oldlenp = len;
1024 	if (error == 0 && newp) {
1025 		error = copyin(newp, str, newlen);
1026 		str[newlen] = 0;
1027 	}
1028 	return (error);
1029 }
1030 
1031 /*
1032  * As above, but read-only.
1033  */
1034 int
1035 sysctl_rdstring(void *oldp, size_t *oldlenp, void *newp, const char *str)
1036 {
1037 	size_t len;
1038 	int error = 0;
1039 
1040 	len = strlen(str) + 1;
1041 	if (oldp && *oldlenp < len)
1042 		return (ENOMEM);
1043 	if (newp)
1044 		return (EPERM);
1045 	*oldlenp = len;
1046 	if (oldp)
1047 		error = copyout(str, oldp, len);
1048 	return (error);
1049 }
1050 
1051 /*
1052  * Validate parameters and get old / set new parameters
1053  * for a structure oriented sysctl function.
1054  */
1055 int
1056 sysctl_struct(void *oldp, size_t *oldlenp, void *newp, size_t newlen, void *sp,
1057     size_t len)
1058 {
1059 	int error = 0;
1060 
1061 	if (oldp && *oldlenp < len)
1062 		return (ENOMEM);
1063 	if (newp && newlen > len)
1064 		return (EINVAL);
1065 	if (oldp) {
1066 		*oldlenp = len;
1067 		error = copyout(sp, oldp, len);
1068 	}
1069 	if (error == 0 && newp)
1070 		error = copyin(newp, sp, len);
1071 	return (error);
1072 }
1073 
1074 /*
1075  * Validate parameters and get old parameters
1076  * for a structure oriented sysctl function.
1077  */
1078 int
1079 sysctl_rdstruct(void *oldp, size_t *oldlenp, void *newp, const void *sp,
1080     size_t len)
1081 {
1082 	int error = 0;
1083 
1084 	if (oldp && *oldlenp < len)
1085 		return (ENOMEM);
1086 	if (newp)
1087 		return (EPERM);
1088 	*oldlenp = len;
1089 	if (oldp)
1090 		error = copyout(sp, oldp, len);
1091 	return (error);
1092 }
1093 
1094 #ifndef SMALL_KERNEL
1095 void
1096 fill_file(struct kinfo_file *kf, struct file *fp, struct filedesc *fdp,
1097 	  int fd, struct vnode *vp, struct process *pr, struct proc *p,
1098 	  struct socket *so, int show_pointers)
1099 {
1100 	struct vattr va;
1101 
1102 	memset(kf, 0, sizeof(*kf));
1103 
1104 	kf->fd_fd = fd;		/* might not really be an fd */
1105 
1106 	if (fp != NULL) {
1107 		if (show_pointers)
1108 			kf->f_fileaddr = PTRTOINT64(fp);
1109 		kf->f_flag = fp->f_flag;
1110 		kf->f_iflags = fp->f_iflags;
1111 		kf->f_type = fp->f_type;
1112 		kf->f_count = fp->f_count;
1113 		if (show_pointers)
1114 			kf->f_ucred = PTRTOINT64(fp->f_cred);
1115 		kf->f_uid = fp->f_cred->cr_uid;
1116 		kf->f_gid = fp->f_cred->cr_gid;
1117 		if (show_pointers)
1118 			kf->f_ops = PTRTOINT64(fp->f_ops);
1119 		if (show_pointers)
1120 			kf->f_data = PTRTOINT64(fp->f_data);
1121 		kf->f_usecount = 0;
1122 
1123 		if (suser(p) == 0 || p->p_ucred->cr_uid == fp->f_cred->cr_uid) {
1124 			mtx_enter(&fp->f_mtx);
1125 			kf->f_offset = fp->f_offset;
1126 			kf->f_rxfer = fp->f_rxfer;
1127 			kf->f_rwfer = fp->f_wxfer;
1128 			kf->f_seek = fp->f_seek;
1129 			kf->f_rbytes = fp->f_rbytes;
1130 			kf->f_wbytes = fp->f_wbytes;
1131 			mtx_leave(&fp->f_mtx);
1132 		} else
1133 			kf->f_offset = -1;
1134 	} else if (vp != NULL) {
1135 		/* fake it */
1136 		kf->f_type = DTYPE_VNODE;
1137 		kf->f_flag = FREAD;
1138 		if (fd == KERN_FILE_TRACE)
1139 			kf->f_flag |= FWRITE;
1140 	} else if (so != NULL) {
1141 		/* fake it */
1142 		kf->f_type = DTYPE_SOCKET;
1143 	}
1144 
1145 	/* information about the object associated with this file */
1146 	switch (kf->f_type) {
1147 	case DTYPE_VNODE:
1148 		if (fp != NULL)
1149 			vp = (struct vnode *)fp->f_data;
1150 
1151 		if (show_pointers)
1152 			kf->v_un = PTRTOINT64(vp->v_un.vu_socket);
1153 		kf->v_type = vp->v_type;
1154 		kf->v_tag = vp->v_tag;
1155 		kf->v_flag = vp->v_flag;
1156 		if (show_pointers)
1157 			kf->v_data = PTRTOINT64(vp->v_data);
1158 		if (show_pointers)
1159 			kf->v_mount = PTRTOINT64(vp->v_mount);
1160 		if (vp->v_mount)
1161 			strlcpy(kf->f_mntonname,
1162 			    vp->v_mount->mnt_stat.f_mntonname,
1163 			    sizeof(kf->f_mntonname));
1164 
1165 		if (VOP_GETATTR(vp, &va, p->p_ucred, p) == 0) {
1166 			kf->va_fileid = va.va_fileid;
1167 			kf->va_mode = MAKEIMODE(va.va_type, va.va_mode);
1168 			kf->va_size = va.va_size;
1169 			kf->va_rdev = va.va_rdev;
1170 			kf->va_fsid = va.va_fsid & 0xffffffff;
1171 			kf->va_nlink = va.va_nlink;
1172 		}
1173 		break;
1174 
1175 	case DTYPE_SOCKET: {
1176 		int locked = 0;
1177 
1178 		if (so == NULL) {
1179 			so = (struct socket *)fp->f_data;
1180 			/* if so is passed as parameter it is already locked */
1181 			switch (so->so_proto->pr_domain->dom_family) {
1182 			case AF_INET:
1183 			case AF_INET6:
1184 				NET_LOCK();
1185 				locked = 1;
1186 				break;
1187 			}
1188 		}
1189 
1190 		kf->so_type = so->so_type;
1191 		kf->so_state = so->so_state;
1192 		if (show_pointers)
1193 			kf->so_pcb = PTRTOINT64(so->so_pcb);
1194 		else
1195 			kf->so_pcb = -1;
1196 		kf->so_protocol = so->so_proto->pr_protocol;
1197 		kf->so_family = so->so_proto->pr_domain->dom_family;
1198 		kf->so_rcv_cc = so->so_rcv.sb_cc;
1199 		kf->so_snd_cc = so->so_snd.sb_cc;
1200 		if (isspliced(so)) {
1201 			if (show_pointers)
1202 				kf->so_splice =
1203 				    PTRTOINT64(so->so_sp->ssp_socket);
1204 			kf->so_splicelen = so->so_sp->ssp_len;
1205 		} else if (issplicedback(so))
1206 			kf->so_splicelen = -1;
1207 		if (so->so_pcb == NULL) {
1208 			if (locked)
1209 				NET_UNLOCK();
1210 			break;
1211 		}
1212 		switch (kf->so_family) {
1213 		case AF_INET: {
1214 			struct inpcb *inpcb = so->so_pcb;
1215 
1216 			NET_ASSERT_LOCKED();
1217 			if (show_pointers)
1218 				kf->inp_ppcb = PTRTOINT64(inpcb->inp_ppcb);
1219 			kf->inp_lport = inpcb->inp_lport;
1220 			kf->inp_laddru[0] = inpcb->inp_laddr.s_addr;
1221 			kf->inp_fport = inpcb->inp_fport;
1222 			kf->inp_faddru[0] = inpcb->inp_faddr.s_addr;
1223 			kf->inp_rtableid = inpcb->inp_rtableid;
1224 			if (so->so_type == SOCK_RAW)
1225 				kf->inp_proto = inpcb->inp_ip.ip_p;
1226 			if (so->so_proto->pr_protocol == IPPROTO_TCP) {
1227 				struct tcpcb *tcpcb = (void *)inpcb->inp_ppcb;
1228 				kf->t_rcv_wnd = tcpcb->rcv_wnd;
1229 				kf->t_snd_wnd = tcpcb->snd_wnd;
1230 				kf->t_snd_cwnd = tcpcb->snd_cwnd;
1231 				kf->t_state = tcpcb->t_state;
1232 			}
1233 			break;
1234 		    }
1235 		case AF_INET6: {
1236 			struct inpcb *inpcb = so->so_pcb;
1237 
1238 			NET_ASSERT_LOCKED();
1239 			if (show_pointers)
1240 				kf->inp_ppcb = PTRTOINT64(inpcb->inp_ppcb);
1241 			kf->inp_lport = inpcb->inp_lport;
1242 			kf->inp_laddru[0] = inpcb->inp_laddr6.s6_addr32[0];
1243 			kf->inp_laddru[1] = inpcb->inp_laddr6.s6_addr32[1];
1244 			kf->inp_laddru[2] = inpcb->inp_laddr6.s6_addr32[2];
1245 			kf->inp_laddru[3] = inpcb->inp_laddr6.s6_addr32[3];
1246 			kf->inp_fport = inpcb->inp_fport;
1247 			kf->inp_faddru[0] = inpcb->inp_faddr6.s6_addr32[0];
1248 			kf->inp_faddru[1] = inpcb->inp_faddr6.s6_addr32[1];
1249 			kf->inp_faddru[2] = inpcb->inp_faddr6.s6_addr32[2];
1250 			kf->inp_faddru[3] = inpcb->inp_faddr6.s6_addr32[3];
1251 			kf->inp_rtableid = inpcb->inp_rtableid;
1252 			if (so->so_type == SOCK_RAW)
1253 				kf->inp_proto = inpcb->inp_ipv6.ip6_nxt;
1254 			if (so->so_proto->pr_protocol == IPPROTO_TCP) {
1255 				struct tcpcb *tcpcb = (void *)inpcb->inp_ppcb;
1256 				kf->t_rcv_wnd = tcpcb->rcv_wnd;
1257 				kf->t_snd_wnd = tcpcb->snd_wnd;
1258 				kf->t_state = tcpcb->t_state;
1259 			}
1260 			break;
1261 		    }
1262 		case AF_UNIX: {
1263 			struct unpcb *unpcb = so->so_pcb;
1264 
1265 			kf->f_msgcount = unpcb->unp_msgcount;
1266 			if (show_pointers) {
1267 				kf->unp_conn	= PTRTOINT64(unpcb->unp_conn);
1268 				kf->unp_refs	= PTRTOINT64(
1269 				    SLIST_FIRST(&unpcb->unp_refs));
1270 				kf->unp_nextref	= PTRTOINT64(
1271 				    SLIST_NEXT(unpcb, unp_nextref));
1272 				kf->v_un	= PTRTOINT64(unpcb->unp_vnode);
1273 				kf->unp_addr	= PTRTOINT64(unpcb->unp_addr);
1274 			}
1275 			if (unpcb->unp_addr != NULL) {
1276 				struct sockaddr_un *un = mtod(unpcb->unp_addr,
1277 				    struct sockaddr_un *);
1278 				memcpy(kf->unp_path, un->sun_path, un->sun_len
1279 				    - offsetof(struct sockaddr_un,sun_path));
1280 			}
1281 			break;
1282 		    }
1283 		}
1284 		if (locked)
1285 			NET_UNLOCK();
1286 		break;
1287 	    }
1288 
1289 	case DTYPE_PIPE: {
1290 		struct pipe *pipe = (struct pipe *)fp->f_data;
1291 
1292 		if (show_pointers)
1293 			kf->pipe_peer = PTRTOINT64(pipe->pipe_peer);
1294 		kf->pipe_state = pipe->pipe_state;
1295 		break;
1296 	    }
1297 
1298 	case DTYPE_KQUEUE: {
1299 		struct kqueue *kqi = (struct kqueue *)fp->f_data;
1300 
1301 		kf->kq_count = kqi->kq_count;
1302 		kf->kq_state = kqi->kq_state;
1303 		break;
1304 	    }
1305 	}
1306 
1307 	/* per-process information for KERN_FILE_BY[PU]ID */
1308 	if (pr != NULL) {
1309 		kf->p_pid = pr->ps_pid;
1310 		kf->p_uid = pr->ps_ucred->cr_uid;
1311 		kf->p_gid = pr->ps_ucred->cr_gid;
1312 		kf->p_tid = -1;
1313 		strlcpy(kf->p_comm, pr->ps_comm, sizeof(kf->p_comm));
1314 	}
1315 	if (fdp != NULL) {
1316 		fdplock(fdp);
1317 		kf->fd_ofileflags = fdp->fd_ofileflags[fd];
1318 		fdpunlock(fdp);
1319 	}
1320 }
1321 
1322 /*
1323  * Get file structures.
1324  */
1325 int
1326 sysctl_file(int *name, u_int namelen, char *where, size_t *sizep,
1327     struct proc *p)
1328 {
1329 	struct kinfo_file *kf;
1330 	struct filedesc *fdp;
1331 	struct file *fp;
1332 	struct process *pr;
1333 	size_t buflen, elem_size, elem_count, outsize;
1334 	char *dp = where;
1335 	int arg, i, error = 0, needed = 0, matched;
1336 	u_int op;
1337 	int show_pointers;
1338 
1339 	if (namelen > 4)
1340 		return (ENOTDIR);
1341 	if (namelen < 4 || name[2] > sizeof(*kf))
1342 		return (EINVAL);
1343 
1344 	buflen = where != NULL ? *sizep : 0;
1345 	op = name[0];
1346 	arg = name[1];
1347 	elem_size = name[2];
1348 	elem_count = name[3];
1349 	outsize = MIN(sizeof(*kf), elem_size);
1350 
1351 	if (elem_size < 1)
1352 		return (EINVAL);
1353 
1354 	show_pointers = suser(curproc) == 0;
1355 
1356 	kf = malloc(sizeof(*kf), M_TEMP, M_WAITOK);
1357 
1358 #define FILLIT2(fp, fdp, i, vp, pr, so) do {				\
1359 	if (buflen >= elem_size && elem_count > 0) {			\
1360 		fill_file(kf, fp, fdp, i, vp, pr, p, so, show_pointers);\
1361 		error = copyout(kf, dp, outsize);			\
1362 		if (error)						\
1363 			break;						\
1364 		dp += elem_size;					\
1365 		buflen -= elem_size;					\
1366 		elem_count--;						\
1367 	}								\
1368 	needed += elem_size;						\
1369 } while (0)
1370 #define FILLIT(fp, fdp, i, vp, pr) \
1371 	FILLIT2(fp, fdp, i, vp, pr, NULL)
1372 #define FILLSO(so) \
1373 	FILLIT2(NULL, NULL, 0, NULL, NULL, so)
1374 
1375 	switch (op) {
1376 	case KERN_FILE_BYFILE:
1377 		/* use the inp-tables to pick up closed connections, too */
1378 		if (arg == DTYPE_SOCKET) {
1379 			struct inpcb *inp;
1380 
1381 			NET_LOCK();
1382 			TAILQ_FOREACH(inp, &tcbtable.inpt_queue, inp_queue)
1383 				FILLSO(inp->inp_socket);
1384 			TAILQ_FOREACH(inp, &udbtable.inpt_queue, inp_queue)
1385 				FILLSO(inp->inp_socket);
1386 			TAILQ_FOREACH(inp, &rawcbtable.inpt_queue, inp_queue)
1387 				FILLSO(inp->inp_socket);
1388 #ifdef INET6
1389 			TAILQ_FOREACH(inp, &rawin6pcbtable.inpt_queue,
1390 			    inp_queue)
1391 				FILLSO(inp->inp_socket);
1392 #endif
1393 			NET_UNLOCK();
1394 		}
1395 		fp = NULL;
1396 		while ((fp = fd_iterfile(fp, p)) != NULL) {
1397 			if ((arg == 0 || fp->f_type == arg)) {
1398 				int af, skip = 0;
1399 				if (arg == DTYPE_SOCKET && fp->f_type == arg) {
1400 					af = ((struct socket *)fp->f_data)->
1401 					    so_proto->pr_domain->dom_family;
1402 					if (af == AF_INET || af == AF_INET6)
1403 						skip = 1;
1404 				}
1405 				if (!skip)
1406 					FILLIT(fp, NULL, 0, NULL, NULL);
1407 			}
1408 		}
1409 		break;
1410 	case KERN_FILE_BYPID:
1411 		/* A arg of -1 indicates all processes */
1412 		if (arg < -1) {
1413 			error = EINVAL;
1414 			break;
1415 		}
1416 		matched = 0;
1417 		LIST_FOREACH(pr, &allprocess, ps_list) {
1418 			/*
1419 			 * skip system, exiting, embryonic and undead
1420 			 * processes
1421 			 */
1422 			if (pr->ps_flags & (PS_SYSTEM | PS_EMBRYO | PS_EXITING))
1423 				continue;
1424 			if (arg > 0 && pr->ps_pid != (pid_t)arg) {
1425 				/* not the pid we are looking for */
1426 				continue;
1427 			}
1428 			matched = 1;
1429 			fdp = pr->ps_fd;
1430 			if (pr->ps_textvp)
1431 				FILLIT(NULL, NULL, KERN_FILE_TEXT, pr->ps_textvp, pr);
1432 			if (fdp->fd_cdir)
1433 				FILLIT(NULL, NULL, KERN_FILE_CDIR, fdp->fd_cdir, pr);
1434 			if (fdp->fd_rdir)
1435 				FILLIT(NULL, NULL, KERN_FILE_RDIR, fdp->fd_rdir, pr);
1436 			if (pr->ps_tracevp)
1437 				FILLIT(NULL, NULL, KERN_FILE_TRACE, pr->ps_tracevp, pr);
1438 			for (i = 0; i < fdp->fd_nfiles; i++) {
1439 				if ((fp = fd_getfile(fdp, i)) == NULL)
1440 					continue;
1441 				FILLIT(fp, fdp, i, NULL, pr);
1442 				FRELE(fp, p);
1443 			}
1444 		}
1445 		if (!matched)
1446 			error = ESRCH;
1447 		break;
1448 	case KERN_FILE_BYUID:
1449 		LIST_FOREACH(pr, &allprocess, ps_list) {
1450 			/*
1451 			 * skip system, exiting, embryonic and undead
1452 			 * processes
1453 			 */
1454 			if (pr->ps_flags & (PS_SYSTEM | PS_EMBRYO | PS_EXITING))
1455 				continue;
1456 			if (arg >= 0 && pr->ps_ucred->cr_uid != (uid_t)arg) {
1457 				/* not the uid we are looking for */
1458 				continue;
1459 			}
1460 			fdp = pr->ps_fd;
1461 			if (fdp->fd_cdir)
1462 				FILLIT(NULL, NULL, KERN_FILE_CDIR, fdp->fd_cdir, pr);
1463 			if (fdp->fd_rdir)
1464 				FILLIT(NULL, NULL, KERN_FILE_RDIR, fdp->fd_rdir, pr);
1465 			if (pr->ps_tracevp)
1466 				FILLIT(NULL, NULL, KERN_FILE_TRACE, pr->ps_tracevp, pr);
1467 			for (i = 0; i < fdp->fd_nfiles; i++) {
1468 				if ((fp = fd_getfile(fdp, i)) == NULL)
1469 					continue;
1470 				FILLIT(fp, fdp, i, NULL, pr);
1471 				FRELE(fp, p);
1472 			}
1473 		}
1474 		break;
1475 	default:
1476 		error = EINVAL;
1477 		break;
1478 	}
1479 	free(kf, M_TEMP, sizeof(*kf));
1480 
1481 	if (!error) {
1482 		if (where == NULL)
1483 			needed += KERN_FILESLOP * elem_size;
1484 		else if (*sizep < needed)
1485 			error = ENOMEM;
1486 		*sizep = needed;
1487 	}
1488 
1489 	return (error);
1490 }
1491 
1492 /*
1493  * try over estimating by 5 procs
1494  */
1495 #define KERN_PROCSLOP	5
1496 
1497 int
1498 sysctl_doproc(int *name, u_int namelen, char *where, size_t *sizep)
1499 {
1500 	struct kinfo_proc *kproc = NULL;
1501 	struct proc *p;
1502 	struct process *pr;
1503 	char *dp;
1504 	int arg, buflen, doingzomb, elem_size, elem_count;
1505 	int error, needed, op;
1506 	int dothreads = 0;
1507 	int show_pointers;
1508 
1509 	dp = where;
1510 	buflen = where != NULL ? *sizep : 0;
1511 	needed = error = 0;
1512 
1513 	if (namelen != 4 || name[2] <= 0 || name[3] < 0 ||
1514 	    name[2] > sizeof(*kproc))
1515 		return (EINVAL);
1516 	op = name[0];
1517 	arg = name[1];
1518 	elem_size = name[2];
1519 	elem_count = name[3];
1520 
1521 	dothreads = op & KERN_PROC_SHOW_THREADS;
1522 	op &= ~KERN_PROC_SHOW_THREADS;
1523 
1524 	show_pointers = suser(curproc) == 0;
1525 
1526 	if (where != NULL)
1527 		kproc = malloc(sizeof(*kproc), M_TEMP, M_WAITOK);
1528 
1529 	pr = LIST_FIRST(&allprocess);
1530 	doingzomb = 0;
1531 again:
1532 	for (; pr != NULL; pr = LIST_NEXT(pr, ps_list)) {
1533 		/* XXX skip processes in the middle of being zapped */
1534 		if (pr->ps_pgrp == NULL)
1535 			continue;
1536 
1537 		/*
1538 		 * Skip embryonic processes.
1539 		 */
1540 		if (pr->ps_flags & PS_EMBRYO)
1541 			continue;
1542 
1543 		/*
1544 		 * TODO - make more efficient (see notes below).
1545 		 */
1546 		switch (op) {
1547 
1548 		case KERN_PROC_PID:
1549 			/* could do this with just a lookup */
1550 			if (pr->ps_pid != (pid_t)arg)
1551 				continue;
1552 			break;
1553 
1554 		case KERN_PROC_PGRP:
1555 			/* could do this by traversing pgrp */
1556 			if (pr->ps_pgrp->pg_id != (pid_t)arg)
1557 				continue;
1558 			break;
1559 
1560 		case KERN_PROC_SESSION:
1561 			if (pr->ps_session->s_leader == NULL ||
1562 			    pr->ps_session->s_leader->ps_pid != (pid_t)arg)
1563 				continue;
1564 			break;
1565 
1566 		case KERN_PROC_TTY:
1567 			if ((pr->ps_flags & PS_CONTROLT) == 0 ||
1568 			    pr->ps_session->s_ttyp == NULL ||
1569 			    pr->ps_session->s_ttyp->t_dev != (dev_t)arg)
1570 				continue;
1571 			break;
1572 
1573 		case KERN_PROC_UID:
1574 			if (pr->ps_ucred->cr_uid != (uid_t)arg)
1575 				continue;
1576 			break;
1577 
1578 		case KERN_PROC_RUID:
1579 			if (pr->ps_ucred->cr_ruid != (uid_t)arg)
1580 				continue;
1581 			break;
1582 
1583 		case KERN_PROC_ALL:
1584 			if (pr->ps_flags & PS_SYSTEM)
1585 				continue;
1586 			break;
1587 
1588 		case KERN_PROC_KTHREAD:
1589 			/* no filtering */
1590 			break;
1591 
1592 		default:
1593 			error = EINVAL;
1594 			goto err;
1595 		}
1596 
1597 		if (buflen >= elem_size && elem_count > 0) {
1598 			fill_kproc(pr, kproc, NULL, show_pointers);
1599 			error = copyout(kproc, dp, elem_size);
1600 			if (error)
1601 				goto err;
1602 			dp += elem_size;
1603 			buflen -= elem_size;
1604 			elem_count--;
1605 		}
1606 		needed += elem_size;
1607 
1608 		/* Skip per-thread entries if not required by op */
1609 		if (!dothreads)
1610 			continue;
1611 
1612 		SMR_TAILQ_FOREACH_LOCKED(p, &pr->ps_threads, p_thr_link) {
1613 			if (buflen >= elem_size && elem_count > 0) {
1614 				fill_kproc(pr, kproc, p, show_pointers);
1615 				error = copyout(kproc, dp, elem_size);
1616 				if (error)
1617 					goto err;
1618 				dp += elem_size;
1619 				buflen -= elem_size;
1620 				elem_count--;
1621 			}
1622 			needed += elem_size;
1623 		}
1624 	}
1625 	if (doingzomb == 0) {
1626 		pr = LIST_FIRST(&zombprocess);
1627 		doingzomb++;
1628 		goto again;
1629 	}
1630 	if (where != NULL) {
1631 		*sizep = dp - where;
1632 		if (needed > *sizep) {
1633 			error = ENOMEM;
1634 			goto err;
1635 		}
1636 	} else {
1637 		needed += KERN_PROCSLOP * elem_size;
1638 		*sizep = needed;
1639 	}
1640 err:
1641 	if (kproc)
1642 		free(kproc, M_TEMP, sizeof(*kproc));
1643 	return (error);
1644 }
1645 
1646 /*
1647  * Fill in a kproc structure for the specified process.
1648  */
1649 void
1650 fill_kproc(struct process *pr, struct kinfo_proc *ki, struct proc *p,
1651     int show_pointers)
1652 {
1653 	struct session *s = pr->ps_session;
1654 	struct tty *tp;
1655 	struct vmspace *vm = pr->ps_vmspace;
1656 	struct timespec booted, st, ut, utc;
1657 	int isthread;
1658 
1659 	isthread = p != NULL;
1660 	if (!isthread)
1661 		p = pr->ps_mainproc;		/* XXX */
1662 
1663 	FILL_KPROC(ki, strlcpy, p, pr, pr->ps_ucred, pr->ps_pgrp,
1664 	    p, pr, s, vm, pr->ps_limit, pr->ps_sigacts, isthread,
1665 	    show_pointers);
1666 
1667 	/* stuff that's too painful to generalize into the macros */
1668 	if (pr->ps_pptr)
1669 		ki->p_ppid = pr->ps_pptr->ps_pid;
1670 	if (s->s_leader)
1671 		ki->p_sid = s->s_leader->ps_pid;
1672 
1673 	if ((pr->ps_flags & PS_CONTROLT) && (tp = s->s_ttyp)) {
1674 		ki->p_tdev = tp->t_dev;
1675 		ki->p_tpgid = tp->t_pgrp ? tp->t_pgrp->pg_id : -1;
1676 		if (show_pointers)
1677 			ki->p_tsess = PTRTOINT64(tp->t_session);
1678 	} else {
1679 		ki->p_tdev = NODEV;
1680 		ki->p_tpgid = -1;
1681 	}
1682 
1683 	/* fixups that can only be done in the kernel */
1684 	if ((pr->ps_flags & PS_ZOMBIE) == 0) {
1685 		if ((pr->ps_flags & PS_EMBRYO) == 0 && vm != NULL)
1686 			ki->p_vm_rssize = vm_resident_count(vm);
1687 		calctsru(isthread ? &p->p_tu : &pr->ps_tu, &ut, &st, NULL);
1688 		ki->p_uutime_sec = ut.tv_sec;
1689 		ki->p_uutime_usec = ut.tv_nsec/1000;
1690 		ki->p_ustime_sec = st.tv_sec;
1691 		ki->p_ustime_usec = st.tv_nsec/1000;
1692 
1693 		/* Convert starting uptime to a starting UTC time. */
1694 		nanoboottime(&booted);
1695 		timespecadd(&booted, &pr->ps_start, &utc);
1696 		ki->p_ustart_sec = utc.tv_sec;
1697 		ki->p_ustart_usec = utc.tv_nsec / 1000;
1698 
1699 #ifdef MULTIPROCESSOR
1700 		if (p->p_cpu != NULL)
1701 			ki->p_cpuid = CPU_INFO_UNIT(p->p_cpu);
1702 #endif
1703 	}
1704 
1705 	/* get %cpu and schedule state: just one thread or sum of all? */
1706 	if (isthread) {
1707 		ki->p_pctcpu = p->p_pctcpu;
1708 		ki->p_stat   = p->p_stat;
1709 	} else {
1710 		ki->p_pctcpu = 0;
1711 		ki->p_stat = (pr->ps_flags & PS_ZOMBIE) ? SDEAD : SIDL;
1712 		SMR_TAILQ_FOREACH_LOCKED(p, &pr->ps_threads, p_thr_link) {
1713 			ki->p_pctcpu += p->p_pctcpu;
1714 			/* find best state: ONPROC > RUN > STOP > SLEEP > .. */
1715 			if (p->p_stat == SONPROC || ki->p_stat == SONPROC)
1716 				ki->p_stat = SONPROC;
1717 			else if (p->p_stat == SRUN || ki->p_stat == SRUN)
1718 				ki->p_stat = SRUN;
1719 			else if (p->p_stat == SSTOP || ki->p_stat == SSTOP)
1720 				ki->p_stat = SSTOP;
1721 			else if (p->p_stat == SSLEEP)
1722 				ki->p_stat = SSLEEP;
1723 		}
1724 	}
1725 }
1726 
1727 int
1728 sysctl_proc_args(int *name, u_int namelen, void *oldp, size_t *oldlenp,
1729     struct proc *cp)
1730 {
1731 	struct process *vpr;
1732 	pid_t pid;
1733 	struct ps_strings pss;
1734 	struct iovec iov;
1735 	struct uio uio;
1736 	int error, cnt, op;
1737 	size_t limit;
1738 	char **rargv, **vargv;		/* reader vs. victim */
1739 	char *rarg, *varg, *buf;
1740 	struct vmspace *vm;
1741 	vaddr_t ps_strings;
1742 
1743 	if (namelen > 2)
1744 		return (ENOTDIR);
1745 	if (namelen < 2)
1746 		return (EINVAL);
1747 
1748 	pid = name[0];
1749 	op = name[1];
1750 
1751 	switch (op) {
1752 	case KERN_PROC_ARGV:
1753 	case KERN_PROC_NARGV:
1754 	case KERN_PROC_ENV:
1755 	case KERN_PROC_NENV:
1756 		break;
1757 	default:
1758 		return (EOPNOTSUPP);
1759 	}
1760 
1761 	if ((vpr = prfind(pid)) == NULL)
1762 		return (ESRCH);
1763 
1764 	if (oldp == NULL) {
1765 		if (op == KERN_PROC_NARGV || op == KERN_PROC_NENV)
1766 			*oldlenp = sizeof(int);
1767 		else
1768 			*oldlenp = ARG_MAX;	/* XXX XXX XXX */
1769 		return (0);
1770 	}
1771 
1772 	/* Either system process or exiting/zombie */
1773 	if (vpr->ps_flags & (PS_SYSTEM | PS_EXITING))
1774 		return (EINVAL);
1775 
1776 	/* Execing - danger. */
1777 	if ((vpr->ps_flags & PS_INEXEC))
1778 		return (EBUSY);
1779 
1780 	/* Only owner or root can get env */
1781 	if ((op == KERN_PROC_NENV || op == KERN_PROC_ENV) &&
1782 	    (vpr->ps_ucred->cr_uid != cp->p_ucred->cr_uid &&
1783 	    (error = suser(cp)) != 0))
1784 		return (error);
1785 
1786 	ps_strings = vpr->ps_strings;
1787 	vm = vpr->ps_vmspace;
1788 	uvmspace_addref(vm);
1789 	vpr = NULL;
1790 
1791 	buf = malloc(PAGE_SIZE, M_TEMP, M_WAITOK);
1792 
1793 	iov.iov_base = &pss;
1794 	iov.iov_len = sizeof(pss);
1795 	uio.uio_iov = &iov;
1796 	uio.uio_iovcnt = 1;
1797 	uio.uio_offset = (off_t)ps_strings;
1798 	uio.uio_resid = sizeof(pss);
1799 	uio.uio_segflg = UIO_SYSSPACE;
1800 	uio.uio_rw = UIO_READ;
1801 	uio.uio_procp = cp;
1802 
1803 	if ((error = uvm_io(&vm->vm_map, &uio, 0)) != 0)
1804 		goto out;
1805 
1806 	if (op == KERN_PROC_NARGV) {
1807 		error = sysctl_rdint(oldp, oldlenp, NULL, pss.ps_nargvstr);
1808 		goto out;
1809 	}
1810 	if (op == KERN_PROC_NENV) {
1811 		error = sysctl_rdint(oldp, oldlenp, NULL, pss.ps_nenvstr);
1812 		goto out;
1813 	}
1814 
1815 	if (op == KERN_PROC_ARGV) {
1816 		cnt = pss.ps_nargvstr;
1817 		vargv = pss.ps_argvstr;
1818 	} else {
1819 		cnt = pss.ps_nenvstr;
1820 		vargv = pss.ps_envstr;
1821 	}
1822 
1823 	/* -1 to have space for a terminating NUL */
1824 	limit = *oldlenp - 1;
1825 	*oldlenp = 0;
1826 
1827 	rargv = oldp;
1828 
1829 	/*
1830 	 * *oldlenp - number of bytes copied out into readers buffer.
1831 	 * limit - maximal number of bytes allowed into readers buffer.
1832 	 * rarg - pointer into readers buffer where next arg will be stored.
1833 	 * rargv - pointer into readers buffer where the next rarg pointer
1834 	 *  will be stored.
1835 	 * vargv - pointer into victim address space where the next argument
1836 	 *  will be read.
1837 	 */
1838 
1839 	/* space for cnt pointers and a NULL */
1840 	rarg = (char *)(rargv + cnt + 1);
1841 	*oldlenp += (cnt + 1) * sizeof(char **);
1842 
1843 	while (cnt > 0 && *oldlenp < limit) {
1844 		size_t len, vstrlen;
1845 
1846 		/* Write to readers argv */
1847 		if ((error = copyout(&rarg, rargv, sizeof(rarg))) != 0)
1848 			goto out;
1849 
1850 		/* read the victim argv */
1851 		iov.iov_base = &varg;
1852 		iov.iov_len = sizeof(varg);
1853 		uio.uio_iov = &iov;
1854 		uio.uio_iovcnt = 1;
1855 		uio.uio_offset = (off_t)(vaddr_t)vargv;
1856 		uio.uio_resid = sizeof(varg);
1857 		uio.uio_segflg = UIO_SYSSPACE;
1858 		uio.uio_rw = UIO_READ;
1859 		uio.uio_procp = cp;
1860 		if ((error = uvm_io(&vm->vm_map, &uio, 0)) != 0)
1861 			goto out;
1862 
1863 		if (varg == NULL)
1864 			break;
1865 
1866 		/*
1867 		 * read the victim arg. We must jump through hoops to avoid
1868 		 * crossing a page boundary too much and returning an error.
1869 		 */
1870 more:
1871 		len = PAGE_SIZE - (((vaddr_t)varg) & PAGE_MASK);
1872 		/* leave space for the terminating NUL */
1873 		iov.iov_base = buf;
1874 		iov.iov_len = len;
1875 		uio.uio_iov = &iov;
1876 		uio.uio_iovcnt = 1;
1877 		uio.uio_offset = (off_t)(vaddr_t)varg;
1878 		uio.uio_resid = len;
1879 		uio.uio_segflg = UIO_SYSSPACE;
1880 		uio.uio_rw = UIO_READ;
1881 		uio.uio_procp = cp;
1882 		if ((error = uvm_io(&vm->vm_map, &uio, 0)) != 0)
1883 			goto out;
1884 
1885 		for (vstrlen = 0; vstrlen < len; vstrlen++) {
1886 			if (buf[vstrlen] == '\0')
1887 				break;
1888 		}
1889 
1890 		/* Don't overflow readers buffer. */
1891 		if (*oldlenp + vstrlen + 1 >= limit) {
1892 			error = ENOMEM;
1893 			goto out;
1894 		}
1895 
1896 		if ((error = copyout(buf, rarg, vstrlen)) != 0)
1897 			goto out;
1898 
1899 		*oldlenp += vstrlen;
1900 		rarg += vstrlen;
1901 
1902 		/* The string didn't end in this page? */
1903 		if (vstrlen == len) {
1904 			varg += vstrlen;
1905 			goto more;
1906 		}
1907 
1908 		/* End of string. Terminate it with a NUL */
1909 		buf[0] = '\0';
1910 		if ((error = copyout(buf, rarg, 1)) != 0)
1911 			goto out;
1912 		*oldlenp += 1;
1913 		rarg += 1;
1914 
1915 		vargv++;
1916 		rargv++;
1917 		cnt--;
1918 	}
1919 
1920 	if (*oldlenp >= limit) {
1921 		error = ENOMEM;
1922 		goto out;
1923 	}
1924 
1925 	/* Write the terminating null */
1926 	rarg = NULL;
1927 	error = copyout(&rarg, rargv, sizeof(rarg));
1928 
1929 out:
1930 	uvmspace_free(vm);
1931 	free(buf, M_TEMP, PAGE_SIZE);
1932 	return (error);
1933 }
1934 
1935 int
1936 sysctl_proc_cwd(int *name, u_int namelen, void *oldp, size_t *oldlenp,
1937     struct proc *cp)
1938 {
1939 	struct process *findpr;
1940 	struct vnode *vp;
1941 	pid_t pid;
1942 	int error;
1943 	size_t lenused, len;
1944 	char *path, *bp, *bend;
1945 
1946 	if (namelen > 1)
1947 		return (ENOTDIR);
1948 	if (namelen < 1)
1949 		return (EINVAL);
1950 
1951 	pid = name[0];
1952 	if ((findpr = prfind(pid)) == NULL)
1953 		return (ESRCH);
1954 
1955 	if (oldp == NULL) {
1956 		*oldlenp = MAXPATHLEN * 4;
1957 		return (0);
1958 	}
1959 
1960 	/* Either system process or exiting/zombie */
1961 	if (findpr->ps_flags & (PS_SYSTEM | PS_EXITING))
1962 		return (EINVAL);
1963 
1964 	/* Only owner or root can get cwd */
1965 	if (findpr->ps_ucred->cr_uid != cp->p_ucred->cr_uid &&
1966 	    (error = suser(cp)) != 0)
1967 		return (error);
1968 
1969 	len = *oldlenp;
1970 	if (len > MAXPATHLEN * 4)
1971 		len = MAXPATHLEN * 4;
1972 	else if (len < 2)
1973 		return (ERANGE);
1974 	*oldlenp = 0;
1975 
1976 	/* snag a reference to the vnode before we can sleep */
1977 	vp = findpr->ps_fd->fd_cdir;
1978 	vref(vp);
1979 
1980 	path = malloc(len, M_TEMP, M_WAITOK);
1981 
1982 	bp = &path[len];
1983 	bend = bp;
1984 	*(--bp) = '\0';
1985 
1986 	/* Same as sys__getcwd */
1987 	error = vfs_getcwd_common(vp, NULL,
1988 	    &bp, path, len / 2, GETCWD_CHECK_ACCESS, cp);
1989 	if (error == 0) {
1990 		*oldlenp = lenused = bend - bp;
1991 		error = copyout(bp, oldp, lenused);
1992 	}
1993 
1994 	vrele(vp);
1995 	free(path, M_TEMP, len);
1996 
1997 	return (error);
1998 }
1999 
2000 int
2001 sysctl_proc_nobroadcastkill(int *name, u_int namelen, void *newp, size_t newlen,
2002     void *oldp, size_t *oldlenp, struct proc *cp)
2003 {
2004 	struct process *findpr;
2005 	pid_t pid;
2006 	int error, flag;
2007 
2008 	if (namelen > 1)
2009 		return (ENOTDIR);
2010 	if (namelen < 1)
2011 		return (EINVAL);
2012 
2013 	pid = name[0];
2014 	if ((findpr = prfind(pid)) == NULL)
2015 		return (ESRCH);
2016 
2017 	/* Either system process or exiting/zombie */
2018 	if (findpr->ps_flags & (PS_SYSTEM | PS_EXITING))
2019 		return (EINVAL);
2020 
2021 	/* Only root can change PS_NOBROADCASTKILL */
2022 	if (newp != 0 && (error = suser(cp)) != 0)
2023 		return (error);
2024 
2025 	/* get the PS_NOBROADCASTKILL flag */
2026 	flag = findpr->ps_flags & PS_NOBROADCASTKILL ? 1 : 0;
2027 
2028 	error = sysctl_int(oldp, oldlenp, newp, newlen, &flag);
2029 	if (error == 0 && newp) {
2030 		if (flag)
2031 			atomic_setbits_int(&findpr->ps_flags,
2032 			    PS_NOBROADCASTKILL);
2033 		else
2034 			atomic_clearbits_int(&findpr->ps_flags,
2035 			    PS_NOBROADCASTKILL);
2036 	}
2037 
2038 	return (error);
2039 }
2040 
2041 /* Arbitrary but reasonable limit for one iteration. */
2042 #define	VMMAP_MAXLEN	MAXPHYS
2043 
2044 int
2045 sysctl_proc_vmmap(int *name, u_int namelen, void *oldp, size_t *oldlenp,
2046     struct proc *cp)
2047 {
2048 	struct process *findpr;
2049 	pid_t pid;
2050 	int error;
2051 	size_t oldlen, len;
2052 	struct kinfo_vmentry *kve, *ukve;
2053 	u_long *ustart, start;
2054 
2055 	if (namelen > 1)
2056 		return (ENOTDIR);
2057 	if (namelen < 1)
2058 		return (EINVAL);
2059 
2060 	/* Provide max buffer length as hint. */
2061 	if (oldp == NULL) {
2062 		if (oldlenp == NULL)
2063 			return (EINVAL);
2064 		else {
2065 			*oldlenp = VMMAP_MAXLEN;
2066 			return (0);
2067 		}
2068 	}
2069 
2070 	pid = name[0];
2071 	if (pid == cp->p_p->ps_pid) {
2072 		/* Self process mapping. */
2073 		findpr = cp->p_p;
2074 	} else if (pid > 0) {
2075 		if ((findpr = prfind(pid)) == NULL)
2076 			return (ESRCH);
2077 
2078 		/* Either system process or exiting/zombie */
2079 		if (findpr->ps_flags & (PS_SYSTEM | PS_EXITING))
2080 			return (EINVAL);
2081 
2082 #if 1
2083 		/* XXX Allow only root for now */
2084 		if ((error = suser(cp)) != 0)
2085 			return (error);
2086 #else
2087 		/* Only owner or root can get vmmap */
2088 		if (findpr->ps_ucred->cr_uid != cp->p_ucred->cr_uid &&
2089 		    (error = suser(cp)) != 0)
2090 			return (error);
2091 #endif
2092 	} else {
2093 		/* Only root can get kernel_map */
2094 		if ((error = suser(cp)) != 0)
2095 			return (error);
2096 		findpr = NULL;
2097 	}
2098 
2099 	/* Check the given size. */
2100 	oldlen = *oldlenp;
2101 	if (oldlen == 0 || oldlen % sizeof(*kve) != 0)
2102 		return (EINVAL);
2103 
2104 	/* Deny huge allocation. */
2105 	if (oldlen > VMMAP_MAXLEN)
2106 		return (EINVAL);
2107 
2108 	/*
2109 	 * Iterate from the given address passed as the first element's
2110 	 * kve_start via oldp.
2111 	 */
2112 	ukve = (struct kinfo_vmentry *)oldp;
2113 	ustart = &ukve->kve_start;
2114 	error = copyin(ustart, &start, sizeof(start));
2115 	if (error != 0)
2116 		return (error);
2117 
2118 	/* Allocate wired memory to not block. */
2119 	kve = malloc(oldlen, M_TEMP, M_WAITOK);
2120 
2121 	/* Set the base address and read entries. */
2122 	kve[0].kve_start = start;
2123 	len = oldlen;
2124 	error = fill_vmmap(findpr, kve, &len);
2125 	if (error != 0 && error != ENOMEM)
2126 		goto done;
2127 	if (len == 0)
2128 		goto done;
2129 
2130 	KASSERT(len <= oldlen);
2131 	KASSERT((len % sizeof(struct kinfo_vmentry)) == 0);
2132 
2133 	error = copyout(kve, oldp, len);
2134 
2135 done:
2136 	*oldlenp = len;
2137 
2138 	free(kve, M_TEMP, oldlen);
2139 
2140 	return (error);
2141 }
2142 #endif
2143 
2144 /*
2145  * Initialize disknames/diskstats for export by sysctl. If update is set,
2146  * then we simply update the disk statistics information.
2147  */
2148 int
2149 sysctl_diskinit(int update, struct proc *p)
2150 {
2151 	struct diskstats *sdk;
2152 	struct disk *dk;
2153 	const char *duid;
2154 	int i, tlen, l;
2155 
2156 	if ((i = rw_enter(&sysctl_disklock, RW_WRITE|RW_INTR)) != 0)
2157 		return i;
2158 
2159 	if (disk_change) {
2160 		for (dk = TAILQ_FIRST(&disklist), tlen = 0; dk;
2161 		    dk = TAILQ_NEXT(dk, dk_link)) {
2162 			if (dk->dk_name)
2163 				tlen += strlen(dk->dk_name);
2164 			tlen += 18;	/* label uid + separators */
2165 		}
2166 		tlen++;
2167 
2168 		if (disknames)
2169 			free(disknames, M_SYSCTL, disknameslen);
2170 		if (diskstats)
2171 			free(diskstats, M_SYSCTL, diskstatslen);
2172 		diskstats = NULL;
2173 		disknames = NULL;
2174 		diskstats = mallocarray(disk_count, sizeof(struct diskstats),
2175 		    M_SYSCTL, M_WAITOK|M_ZERO);
2176 		diskstatslen = disk_count * sizeof(struct diskstats);
2177 		disknames = malloc(tlen, M_SYSCTL, M_WAITOK|M_ZERO);
2178 		disknameslen = tlen;
2179 		disknames[0] = '\0';
2180 
2181 		for (dk = TAILQ_FIRST(&disklist), i = 0, l = 0; dk;
2182 		    dk = TAILQ_NEXT(dk, dk_link), i++) {
2183 			duid = NULL;
2184 			if (dk->dk_label && !duid_iszero(dk->dk_label->d_uid))
2185 				duid = duid_format(dk->dk_label->d_uid);
2186 			snprintf(disknames + l, tlen - l, "%s:%s,",
2187 			    dk->dk_name ? dk->dk_name : "",
2188 			    duid ? duid : "");
2189 			l += strlen(disknames + l);
2190 			sdk = diskstats + i;
2191 			strlcpy(sdk->ds_name, dk->dk_name,
2192 			    sizeof(sdk->ds_name));
2193 			mtx_enter(&dk->dk_mtx);
2194 			sdk->ds_busy = dk->dk_busy;
2195 			sdk->ds_rxfer = dk->dk_rxfer;
2196 			sdk->ds_wxfer = dk->dk_wxfer;
2197 			sdk->ds_seek = dk->dk_seek;
2198 			sdk->ds_rbytes = dk->dk_rbytes;
2199 			sdk->ds_wbytes = dk->dk_wbytes;
2200 			sdk->ds_attachtime = dk->dk_attachtime;
2201 			sdk->ds_timestamp = dk->dk_timestamp;
2202 			sdk->ds_time = dk->dk_time;
2203 			mtx_leave(&dk->dk_mtx);
2204 		}
2205 
2206 		/* Eliminate trailing comma */
2207 		if (l != 0)
2208 			disknames[l - 1] = '\0';
2209 		disk_change = 0;
2210 	} else if (update) {
2211 		/* Just update, number of drives hasn't changed */
2212 		for (dk = TAILQ_FIRST(&disklist), i = 0; dk;
2213 		    dk = TAILQ_NEXT(dk, dk_link), i++) {
2214 			sdk = diskstats + i;
2215 			strlcpy(sdk->ds_name, dk->dk_name,
2216 			    sizeof(sdk->ds_name));
2217 			mtx_enter(&dk->dk_mtx);
2218 			sdk->ds_busy = dk->dk_busy;
2219 			sdk->ds_rxfer = dk->dk_rxfer;
2220 			sdk->ds_wxfer = dk->dk_wxfer;
2221 			sdk->ds_seek = dk->dk_seek;
2222 			sdk->ds_rbytes = dk->dk_rbytes;
2223 			sdk->ds_wbytes = dk->dk_wbytes;
2224 			sdk->ds_attachtime = dk->dk_attachtime;
2225 			sdk->ds_timestamp = dk->dk_timestamp;
2226 			sdk->ds_time = dk->dk_time;
2227 			mtx_leave(&dk->dk_mtx);
2228 		}
2229 	}
2230 	rw_exit_write(&sysctl_disklock);
2231 	return 0;
2232 }
2233 
2234 #if defined(SYSVMSG) || defined(SYSVSEM) || defined(SYSVSHM)
2235 int
2236 sysctl_sysvipc(int *name, u_int namelen, void *where, size_t *sizep)
2237 {
2238 #ifdef SYSVSEM
2239 	struct sem_sysctl_info *semsi;
2240 #endif
2241 #ifdef SYSVSHM
2242 	struct shm_sysctl_info *shmsi;
2243 #endif
2244 	size_t infosize, dssize, tsize, buflen, bufsiz;
2245 	int i, nds, error, ret;
2246 	void *buf;
2247 
2248 	if (namelen != 1)
2249 		return (EINVAL);
2250 
2251 	buflen = *sizep;
2252 
2253 	switch (*name) {
2254 	case KERN_SYSVIPC_MSG_INFO:
2255 #ifdef SYSVMSG
2256 		return (sysctl_sysvmsg(name, namelen, where, sizep));
2257 #else
2258 		return (EOPNOTSUPP);
2259 #endif
2260 	case KERN_SYSVIPC_SEM_INFO:
2261 #ifdef SYSVSEM
2262 		infosize = sizeof(semsi->seminfo);
2263 		nds = seminfo.semmni;
2264 		dssize = sizeof(semsi->semids[0]);
2265 		break;
2266 #else
2267 		return (EOPNOTSUPP);
2268 #endif
2269 	case KERN_SYSVIPC_SHM_INFO:
2270 #ifdef SYSVSHM
2271 		infosize = sizeof(shmsi->shminfo);
2272 		nds = shminfo.shmmni;
2273 		dssize = sizeof(shmsi->shmids[0]);
2274 		break;
2275 #else
2276 		return (EOPNOTSUPP);
2277 #endif
2278 	default:
2279 		return (EINVAL);
2280 	}
2281 	tsize = infosize + (nds * dssize);
2282 
2283 	/* Return just the total size required. */
2284 	if (where == NULL) {
2285 		*sizep = tsize;
2286 		return (0);
2287 	}
2288 
2289 	/* Not enough room for even the info struct. */
2290 	if (buflen < infosize) {
2291 		*sizep = 0;
2292 		return (ENOMEM);
2293 	}
2294 	bufsiz = min(tsize, buflen);
2295 	buf = malloc(bufsiz, M_TEMP, M_WAITOK|M_ZERO);
2296 
2297 	switch (*name) {
2298 #ifdef SYSVSEM
2299 	case KERN_SYSVIPC_SEM_INFO:
2300 		semsi = (struct sem_sysctl_info *)buf;
2301 		semsi->seminfo = seminfo;
2302 		break;
2303 #endif
2304 #ifdef SYSVSHM
2305 	case KERN_SYSVIPC_SHM_INFO:
2306 		shmsi = (struct shm_sysctl_info *)buf;
2307 		shmsi->shminfo = shminfo;
2308 		break;
2309 #endif
2310 	}
2311 	buflen -= infosize;
2312 
2313 	ret = 0;
2314 	if (buflen > 0) {
2315 		/* Fill in the IPC data structures.  */
2316 		for (i = 0; i < nds; i++) {
2317 			if (buflen < dssize) {
2318 				ret = ENOMEM;
2319 				break;
2320 			}
2321 			switch (*name) {
2322 #ifdef SYSVSEM
2323 			case KERN_SYSVIPC_SEM_INFO:
2324 				if (sema[i] != NULL)
2325 					memcpy(&semsi->semids[i], sema[i],
2326 					    dssize);
2327 				else
2328 					memset(&semsi->semids[i], 0, dssize);
2329 				break;
2330 #endif
2331 #ifdef SYSVSHM
2332 			case KERN_SYSVIPC_SHM_INFO:
2333 				if (shmsegs[i] != NULL)
2334 					memcpy(&shmsi->shmids[i], shmsegs[i],
2335 					    dssize);
2336 				else
2337 					memset(&shmsi->shmids[i], 0, dssize);
2338 				break;
2339 #endif
2340 			}
2341 			buflen -= dssize;
2342 		}
2343 	}
2344 	*sizep -= buflen;
2345 	error = copyout(buf, where, *sizep);
2346 	free(buf, M_TEMP, bufsiz);
2347 	/* If copyout succeeded, use return code set earlier. */
2348 	return (error ? error : ret);
2349 }
2350 #endif /* SYSVMSG || SYSVSEM || SYSVSHM */
2351 
2352 #ifndef	SMALL_KERNEL
2353 
2354 int
2355 sysctl_intrcnt(int *name, u_int namelen, void *oldp, size_t *oldlenp)
2356 {
2357 	return (evcount_sysctl(name, namelen, oldp, oldlenp, NULL, 0));
2358 }
2359 
2360 
2361 int
2362 sysctl_sensors(int *name, u_int namelen, void *oldp, size_t *oldlenp,
2363     void *newp, size_t newlen)
2364 {
2365 	struct ksensor *ks;
2366 	struct sensor *us;
2367 	struct ksensordev *ksd;
2368 	struct sensordev *usd;
2369 	int dev, numt, ret;
2370 	enum sensor_type type;
2371 
2372 	if (namelen != 1 && namelen != 3)
2373 		return (ENOTDIR);
2374 
2375 	dev = name[0];
2376 	if (namelen == 1) {
2377 		ret = sensordev_get(dev, &ksd);
2378 		if (ret)
2379 			return (ret);
2380 
2381 		/* Grab a copy, to clear the kernel pointers */
2382 		usd = malloc(sizeof(*usd), M_TEMP, M_WAITOK|M_ZERO);
2383 		usd->num = ksd->num;
2384 		strlcpy(usd->xname, ksd->xname, sizeof(usd->xname));
2385 		memcpy(usd->maxnumt, ksd->maxnumt, sizeof(usd->maxnumt));
2386 		usd->sensors_count = ksd->sensors_count;
2387 
2388 		ret = sysctl_rdstruct(oldp, oldlenp, newp, usd,
2389 		    sizeof(struct sensordev));
2390 
2391 		free(usd, M_TEMP, sizeof(*usd));
2392 		return (ret);
2393 	}
2394 
2395 	type = name[1];
2396 	numt = name[2];
2397 
2398 	ret = sensor_find(dev, type, numt, &ks);
2399 	if (ret)
2400 		return (ret);
2401 
2402 	/* Grab a copy, to clear the kernel pointers */
2403 	us = malloc(sizeof(*us), M_TEMP, M_WAITOK|M_ZERO);
2404 	memcpy(us->desc, ks->desc, sizeof(us->desc));
2405 	us->tv = ks->tv;
2406 	us->value = ks->value;
2407 	us->type = ks->type;
2408 	us->status = ks->status;
2409 	us->numt = ks->numt;
2410 	us->flags = ks->flags;
2411 
2412 	ret = sysctl_rdstruct(oldp, oldlenp, newp, us,
2413 	    sizeof(struct sensor));
2414 	free(us, M_TEMP, sizeof(*us));
2415 	return (ret);
2416 }
2417 #endif	/* SMALL_KERNEL */
2418 
2419 int
2420 sysctl_cptime2(int *name, u_int namelen, void *oldp, size_t *oldlenp,
2421     void *newp, size_t newlen)
2422 {
2423 	CPU_INFO_ITERATOR cii;
2424 	struct cpu_info *ci;
2425 	int found = 0;
2426 
2427 	if (namelen != 1)
2428 		return (ENOTDIR);
2429 
2430 	CPU_INFO_FOREACH(cii, ci) {
2431 		if (name[0] == CPU_INFO_UNIT(ci)) {
2432 			found = 1;
2433 			break;
2434 		}
2435 	}
2436 	if (!found)
2437 		return (ENOENT);
2438 
2439 	return (sysctl_rdstruct(oldp, oldlenp, newp,
2440 	    &ci->ci_schedstate.spc_cp_time,
2441 	    sizeof(ci->ci_schedstate.spc_cp_time)));
2442 }
2443 
2444 #if NAUDIO > 0
2445 int
2446 sysctl_audio(int *name, u_int namelen, void *oldp, size_t *oldlenp,
2447     void *newp, size_t newlen)
2448 {
2449 	if (namelen != 1)
2450 		return (ENOTDIR);
2451 
2452 	if (name[0] != KERN_AUDIO_RECORD)
2453 		return (ENOENT);
2454 
2455 	return (sysctl_int(oldp, oldlenp, newp, newlen, &audio_record_enable));
2456 }
2457 #endif
2458 
2459 #if NVIDEO > 0
2460 int
2461 sysctl_video(int *name, u_int namelen, void *oldp, size_t *oldlenp,
2462     void *newp, size_t newlen)
2463 {
2464 	if (namelen != 1)
2465 		return (ENOTDIR);
2466 
2467 	if (name[0] != KERN_VIDEO_RECORD)
2468 		return (ENOENT);
2469 
2470 	return (sysctl_int(oldp, oldlenp, newp, newlen, &video_record_enable));
2471 }
2472 #endif
2473 
2474 int
2475 sysctl_cpustats(int *name, u_int namelen, void *oldp, size_t *oldlenp,
2476     void *newp, size_t newlen)
2477 {
2478 	CPU_INFO_ITERATOR cii;
2479 	struct cpustats cs;
2480 	struct cpu_info *ci;
2481 	int found = 0;
2482 
2483 	if (namelen != 1)
2484 		return (ENOTDIR);
2485 
2486 	CPU_INFO_FOREACH(cii, ci) {
2487 		if (name[0] == CPU_INFO_UNIT(ci)) {
2488 			found = 1;
2489 			break;
2490 		}
2491 	}
2492 	if (!found)
2493 		return (ENOENT);
2494 
2495 	memcpy(&cs.cs_time, &ci->ci_schedstate.spc_cp_time, sizeof(cs.cs_time));
2496 	cs.cs_flags = 0;
2497 	if (cpu_is_online(ci))
2498 		cs.cs_flags |= CPUSTATS_ONLINE;
2499 
2500 	return (sysctl_rdstruct(oldp, oldlenp, newp, &cs, sizeof(cs)));
2501 }
2502 
2503 int
2504 sysctl_utc_offset(void *oldp, size_t *oldlenp, void *newp, size_t newlen)
2505 {
2506 	struct timespec adjusted, now;
2507 	int adjustment_seconds, error, new_offset_minutes, old_offset_minutes;
2508 
2509 	old_offset_minutes = utc_offset / 60;	/* seconds -> minutes */
2510 	if (securelevel > 0)
2511 		return sysctl_rdint(oldp, oldlenp, newp, old_offset_minutes);
2512 
2513 	new_offset_minutes = old_offset_minutes;
2514 	error = sysctl_int(oldp, oldlenp, newp, newlen, &new_offset_minutes);
2515 	if (error)
2516 		return error;
2517 	if (new_offset_minutes < -24 * 60 || new_offset_minutes > 24 * 60)
2518 		return EINVAL;
2519 	if (new_offset_minutes == old_offset_minutes)
2520 		return 0;
2521 
2522 	utc_offset = new_offset_minutes * 60;	/* minutes -> seconds */
2523 	adjustment_seconds = (new_offset_minutes - old_offset_minutes) * 60;
2524 
2525 	nanotime(&now);
2526 	adjusted = now;
2527 	adjusted.tv_sec -= adjustment_seconds;
2528 	tc_setrealtimeclock(&adjusted);
2529 	resettodr();
2530 
2531 	return 0;
2532 }
2533