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