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