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