init_sysctl.c revision 1.93
1/* $NetBSD: init_sysctl.c,v 1.93 2006/11/27 17:45:36 elad 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 2006/11/27 17:45:36 elad 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 */ 87int security_setidcore_dump; 88char security_setidcore_path[MAXPATHLEN] = "/var/crash/%n.core"; 89uid_t security_setidcore_owner = 0; 90gid_t security_setidcore_group = 0; 91mode_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 100int dcopyout(struct lwp *, const void *, void *, size_t); 101 102int 103dcopyout(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 131static int 132sysctl_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 145static int sysctl_kern_trigger_panic(SYSCTLFN_PROTO); 146#endif 147static int sysctl_kern_maxvnodes(SYSCTLFN_PROTO); 148static int sysctl_kern_rtc_offset(SYSCTLFN_PROTO); 149static int sysctl_kern_maxproc(SYSCTLFN_PROTO); 150static int sysctl_kern_hostid(SYSCTLFN_PROTO); 151static int sysctl_setlen(SYSCTLFN_PROTO); 152static int sysctl_kern_clockrate(SYSCTLFN_PROTO); 153static int sysctl_kern_file(SYSCTLFN_PROTO); 154static int sysctl_kern_autonice(SYSCTLFN_PROTO); 155static int sysctl_msgbuf(SYSCTLFN_PROTO); 156static int sysctl_kern_defcorename(SYSCTLFN_PROTO); 157static int sysctl_kern_cptime(SYSCTLFN_PROTO); 158#if NPTY > 0 159static int sysctl_kern_maxptys(SYSCTLFN_PROTO); 160#endif /* NPTY > 0 */ 161static int sysctl_kern_sbmax(SYSCTLFN_PROTO); 162static int sysctl_kern_urnd(SYSCTLFN_PROTO); 163static int sysctl_kern_arnd(SYSCTLFN_PROTO); 164static int sysctl_kern_lwp(SYSCTLFN_PROTO); 165static int sysctl_kern_forkfsleep(SYSCTLFN_PROTO); 166static int sysctl_kern_root_partition(SYSCTLFN_PROTO); 167static int sysctl_kern_drivers(SYSCTLFN_PROTO); 168static int sysctl_kern_file2(SYSCTLFN_PROTO); 169static int sysctl_security_setidcore(SYSCTLFN_PROTO); 170static int sysctl_security_setidcorename(SYSCTLFN_PROTO); 171static int sysctl_kern_cpid(SYSCTLFN_PROTO); 172static int sysctl_doeproc(SYSCTLFN_PROTO); 173static int sysctl_kern_proc_args(SYSCTLFN_PROTO); 174static int sysctl_hw_usermem(SYSCTLFN_PROTO); 175static int sysctl_hw_cnmagic(SYSCTLFN_PROTO); 176static int sysctl_hw_ncpu(SYSCTLFN_PROTO); 177 178static void fill_kproc2(struct proc *, struct kinfo_proc2 *); 179static void fill_lwp(struct lwp *l, struct kinfo_lwp *kl); 180static 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 */ 195SYSCTL_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 */ 285SYSCTL_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 838SYSCTL_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 884SYSCTL_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 */ 977struct ctldebug /* debug0, */ /* debug1, */ debug2, debug3, debug4; 978struct ctldebug debug5, debug6, debug7, debug8, debug9; 979struct ctldebug debug10, debug11, debug12, debug13, debug14; 980struct ctldebug debug15, debug16, debug17, debug18, debug19; 981static 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 */ 993SYSCTL_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 1059static int 1060sysctl_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 */ 1084static int 1085sysctl_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 */ 1115static int 1116sysctl_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 */ 1151static int 1152sysctl_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 */ 1179static int 1180sysctl_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 */ 1202static int 1203sysctl_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 */ 1227static int 1228sysctl_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 */ 1248static int 1249sysctl_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 */ 1304static int 1305sysctl_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 */ 1339static int 1340sysctl_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 */ 1409static int 1410sysctl_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 } 1435done: 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 */ 1444static int 1445sysctl_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 */ 1546static int 1547sysctl_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 */ 1573static int 1574sysctl_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 */ 1595static int 1596sysctl_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 */ 1617static int 1618sysctl_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 */ 1645static int 1646sysctl_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 */ 1707static int 1708sysctl_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 */ 1740static int 1741sysctl_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 */ 1753static int 1754sysctl_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 */ 1804static int 1805sysctl_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 if (elem_count > 0) { 1855 needed += elem_size; 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 if (elem_count > 0) { 1892 needed += elem_size; 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 1911static void 1912fill_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 1950static int 1951sysctl_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; 2002again: 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 */ 2148static int 2149sysctl_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_process(l->l_cred, KAUTH_PROCESS_CANSEE, 2202 p, NULL, NULL, NULL)) { 2203 error = EPERM; 2204 goto out_locked; 2205 } 2206 } 2207 2208 if (oldp == NULL) { 2209 if (type == KERN_PROC_NARGV || type == KERN_PROC_NENV) 2210 *oldlenp = sizeof (int); 2211 else 2212 *oldlenp = ARG_MAX; /* XXX XXX XXX */ 2213 error = 0; 2214 goto out_locked; 2215 } 2216 2217 /* 2218 * Zombies don't have a stack, so we can't read their psstrings. 2219 * System processes also don't have a user stack. 2220 */ 2221 if (P_ZOMBIE(p) || (p->p_flag & P_SYSTEM) != 0) { 2222 error = EINVAL; 2223 goto out_locked; 2224 } 2225 2226 /* 2227 * Lock the process down in memory. 2228 */ 2229 /* XXXCDC: how should locking work here? */ 2230 if ((p->p_flag & P_WEXIT) || (p->p_vmspace->vm_refcnt < 1)) { 2231 error = EFAULT; 2232 goto out_locked; 2233 } 2234 2235 psstr_addr = (vaddr_t)p->p_psstr; 2236 if (type == KERN_PROC_ARGV || type == KERN_PROC_NARGV) { 2237 offsetn = p->p_psnargv; 2238 offsetv = p->p_psargv; 2239 } else { 2240 offsetn = p->p_psnenv; 2241 offsetv = p->p_psenv; 2242 } 2243 vmspace = p->p_vmspace; 2244 vmspace->vm_refcnt++; /* XXX */ 2245 2246 proclist_unlock_read(); 2247 2248 /* 2249 * Allocate a temporary buffer to hold the arguments. 2250 */ 2251 arg = malloc(PAGE_SIZE, M_TEMP, M_WAITOK); 2252 2253 /* 2254 * Read in the ps_strings structure. 2255 */ 2256 aiov.iov_base = &pss; 2257 aiov.iov_len = sizeof(pss); 2258 auio.uio_iov = &aiov; 2259 auio.uio_iovcnt = 1; 2260 auio.uio_offset = psstr_addr; 2261 auio.uio_resid = sizeof(pss); 2262 auio.uio_rw = UIO_READ; 2263 UIO_SETUP_SYSSPACE(&auio); 2264 error = uvm_io(&vmspace->vm_map, &auio); 2265 if (error) 2266 goto done; 2267 2268 memcpy(&nargv, (char *)&pss + offsetn, sizeof(nargv)); 2269 if (type == KERN_PROC_NARGV || type == KERN_PROC_NENV) { 2270 error = dcopyout(l, &nargv, oldp, sizeof(nargv)); 2271 *oldlenp = sizeof(nargv); 2272 goto done; 2273 } 2274 /* 2275 * Now read the address of the argument vector. 2276 */ 2277 switch (type) { 2278 case KERN_PROC_ARGV: 2279 /* FALLTHROUGH */ 2280 case KERN_PROC_ENV: 2281 memcpy(&tmp, (char *)&pss + offsetv, sizeof(tmp)); 2282 break; 2283 default: 2284 return (EINVAL); 2285 } 2286 2287#ifdef COMPAT_NETBSD32 2288 if (p->p_flag & P_32) 2289 len = sizeof(netbsd32_charp) * nargv; 2290 else 2291#endif 2292 len = sizeof(char *) * nargv; 2293 2294 argv = malloc(len, M_TEMP, M_WAITOK); 2295 2296 aiov.iov_base = argv; 2297 aiov.iov_len = len; 2298 auio.uio_iov = &aiov; 2299 auio.uio_iovcnt = 1; 2300 auio.uio_offset = (off_t)(unsigned long)tmp; 2301 auio.uio_resid = len; 2302 auio.uio_rw = UIO_READ; 2303 UIO_SETUP_SYSSPACE(&auio); 2304 error = uvm_io(&vmspace->vm_map, &auio); 2305 if (error) 2306 goto done; 2307 2308 /* 2309 * Now copy each string. 2310 */ 2311 len = 0; /* bytes written to user buffer */ 2312 for (i = 0; i < nargv; i++) { 2313 int finished = 0; 2314 vaddr_t base; 2315 size_t xlen; 2316 int j; 2317 2318#ifdef COMPAT_NETBSD32 2319 if (p->p_flag & P_32) { 2320 netbsd32_charp *argv32; 2321 2322 argv32 = (netbsd32_charp *)argv; 2323 2324 base = (vaddr_t)NETBSD32PTR64(argv32[i]); 2325 } else 2326#endif 2327 base = (vaddr_t)argv[i]; 2328 2329 while (!finished) { 2330 xlen = PAGE_SIZE - (base & PAGE_MASK); 2331 2332 aiov.iov_base = arg; 2333 aiov.iov_len = PAGE_SIZE; 2334 auio.uio_iov = &aiov; 2335 auio.uio_iovcnt = 1; 2336 auio.uio_offset = base; 2337 auio.uio_resid = xlen; 2338 auio.uio_rw = UIO_READ; 2339 UIO_SETUP_SYSSPACE(&auio); 2340 error = uvm_io(&vmspace->vm_map, &auio); 2341 if (error) 2342 goto done; 2343 2344 /* Look for the end of the string */ 2345 for (j = 0; j < xlen; j++) { 2346 if (arg[j] == '\0') { 2347 xlen = j + 1; 2348 finished = 1; 2349 break; 2350 } 2351 } 2352 2353 /* Check for user buffer overflow */ 2354 if (len + xlen > *oldlenp) { 2355 finished = 1; 2356 if (len > *oldlenp) 2357 xlen = 0; 2358 else 2359 xlen = *oldlenp - len; 2360 } 2361 2362 /* Copyout the page */ 2363 error = dcopyout(l, arg, (char *)oldp + len, xlen); 2364 if (error) 2365 goto done; 2366 2367 len += xlen; 2368 base += xlen; 2369 } 2370 } 2371 *oldlenp = len; 2372 2373done: 2374 if (argv != NULL) 2375 free(argv, M_TEMP); 2376 2377 uvmspace_free(vmspace); 2378 2379 free(arg, M_TEMP); 2380 return error; 2381 2382out_locked: 2383 proclist_unlock_read(); 2384 return error; 2385} 2386 2387static int 2388sysctl_security_setidcore(SYSCTLFN_ARGS) 2389{ 2390 int newsize, error; 2391 struct sysctlnode node; 2392 2393 node = *rnode; 2394 node.sysctl_data = &newsize; 2395 newsize = *(int *)rnode->sysctl_data; 2396 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 2397 if (error || newp == NULL) 2398 return error; 2399 2400 if (kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_SETIDCORE, 2401 0, NULL, NULL, NULL)) 2402 return (EPERM); 2403 2404 *(int *)rnode->sysctl_data = newsize; 2405 2406 return 0; 2407} 2408 2409static int 2410sysctl_security_setidcorename(SYSCTLFN_ARGS) 2411{ 2412 int error; 2413 char *newsetidcorename; 2414 struct sysctlnode node; 2415 2416 newsetidcorename = PNBUF_GET(); 2417 node = *rnode; 2418 node.sysctl_data = newsetidcorename; 2419 memcpy(node.sysctl_data, rnode->sysctl_data, MAXPATHLEN); 2420 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 2421 if (error || newp == NULL) { 2422 goto out; 2423 } 2424 if (kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_SETIDCORE, 2425 0, NULL, NULL, NULL)) { 2426 error = EPERM; 2427 goto out; 2428 } 2429 if (strlen(newsetidcorename) == 0) { 2430 error = EINVAL; 2431 goto out; 2432 } 2433 memcpy(rnode->sysctl_data, node.sysctl_data, MAXPATHLEN); 2434out: 2435 PNBUF_PUT(newsetidcorename); 2436 return error; 2437} 2438 2439/* 2440 * sysctl helper routine for kern.cp_id node. maps cpus to their 2441 * cpuids. 2442 */ 2443static int 2444sysctl_kern_cpid(SYSCTLFN_ARGS) 2445{ 2446 struct sysctlnode node = *rnode; 2447 2448#ifndef MULTIPROCESSOR 2449 uint64_t id; 2450 2451 if (namelen == 1) { 2452 if (name[0] != 0) 2453 return (ENOENT); 2454 /* 2455 * you're allowed to ask for the zero'th processor 2456 */ 2457 name++; 2458 namelen--; 2459 } 2460 node.sysctl_data = &id; 2461 node.sysctl_size = sizeof(id); 2462 id = cpu_number(); 2463 return (sysctl_lookup(SYSCTLFN_CALL(&node))); 2464 2465#else /* MULTIPROCESSOR */ 2466 uint64_t *cp_id = NULL; 2467 int error, n = sysctl_ncpus(); 2468 struct cpu_info *ci; 2469 CPU_INFO_ITERATOR cii; 2470 2471 /* 2472 * here you may either retrieve a single cpu id or the whole 2473 * set. the size you get back when probing depends on what 2474 * you ask for. 2475 */ 2476 switch (namelen) { 2477 case 0: 2478 node.sysctl_size = n * sizeof(uint64_t); 2479 n = -2; /* ALL */ 2480 break; 2481 case 1: 2482 if (name[0] < 0 || name[0] >= n) 2483 return (ENOENT); /* ENOSUCHPROCESSOR */ 2484 node.sysctl_size = sizeof(uint64_t); 2485 n = name[0]; 2486 /* 2487 * adjust these so that sysctl_lookup() will be happy 2488 */ 2489 name++; 2490 namelen--; 2491 break; 2492 default: 2493 return (EINVAL); 2494 } 2495 2496 cp_id = malloc(node.sysctl_size, M_TEMP, M_WAITOK|M_CANFAIL); 2497 if (cp_id == NULL) 2498 return (ENOMEM); 2499 node.sysctl_data = cp_id; 2500 memset(cp_id, 0, node.sysctl_size); 2501 2502 for (CPU_INFO_FOREACH(cii, ci)) { 2503 if (n <= 0) 2504 cp_id[0] = ci->ci_cpuid; 2505 /* 2506 * if a specific processor was requested and we just 2507 * did it, we're done here 2508 */ 2509 if (n == 0) 2510 break; 2511 /* 2512 * if doing "all", skip to next cp_id slot for next processor 2513 */ 2514 if (n == -2) 2515 cp_id++; 2516 /* 2517 * if we're doing a specific processor, we're one 2518 * processor closer 2519 */ 2520 if (n > 0) 2521 n--; 2522 } 2523 2524 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 2525 free(node.sysctl_data, M_TEMP); 2526 return (error); 2527 2528#endif /* MULTIPROCESSOR */ 2529} 2530 2531/* 2532 * sysctl helper routine for hw.usermem and hw.usermem64. values are 2533 * calculate on the fly taking into account integer overflow and the 2534 * current wired count. 2535 */ 2536static int 2537sysctl_hw_usermem(SYSCTLFN_ARGS) 2538{ 2539 u_int ui; 2540 u_quad_t uq; 2541 struct sysctlnode node; 2542 2543 node = *rnode; 2544 switch (rnode->sysctl_num) { 2545 case HW_USERMEM: 2546 if ((ui = physmem - uvmexp.wired) > (UINT_MAX / PAGE_SIZE)) 2547 ui = UINT_MAX; 2548 else 2549 ui *= PAGE_SIZE; 2550 node.sysctl_data = &ui; 2551 break; 2552 case HW_USERMEM64: 2553 uq = (u_quad_t)(physmem - uvmexp.wired) * PAGE_SIZE; 2554 node.sysctl_data = &uq; 2555 break; 2556 default: 2557 return (EINVAL); 2558 } 2559 2560 return (sysctl_lookup(SYSCTLFN_CALL(&node))); 2561} 2562 2563/* 2564 * sysctl helper routine for kern.cnmagic node. pulls the old value 2565 * out, encoded, and stuffs the new value in for decoding. 2566 */ 2567static int 2568sysctl_hw_cnmagic(SYSCTLFN_ARGS) 2569{ 2570 char magic[CNS_LEN]; 2571 int error; 2572 struct sysctlnode node; 2573 2574 if (oldp) 2575 cn_get_magic(magic, CNS_LEN); 2576 node = *rnode; 2577 node.sysctl_data = &magic[0]; 2578 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 2579 if (error || newp == NULL) 2580 return (error); 2581 2582 return (cn_set_magic(magic)); 2583} 2584 2585static int 2586sysctl_hw_ncpu(SYSCTLFN_ARGS) 2587{ 2588 int ncpu; 2589 struct sysctlnode node; 2590 2591 ncpu = sysctl_ncpus(); 2592 node = *rnode; 2593 node.sysctl_data = &ncpu; 2594 2595 return (sysctl_lookup(SYSCTLFN_CALL(&node))); 2596} 2597 2598 2599/* 2600 * ******************************************************************** 2601 * section 3: public helper routines that are used for more than one 2602 * node 2603 * ******************************************************************** 2604 */ 2605 2606/* 2607 * sysctl helper routine for the kern.root_device node and some ports' 2608 * machdep.root_device nodes. 2609 */ 2610int 2611sysctl_root_device(SYSCTLFN_ARGS) 2612{ 2613 struct sysctlnode node; 2614 2615 node = *rnode; 2616 node.sysctl_data = root_device->dv_xname; 2617 node.sysctl_size = strlen(root_device->dv_xname) + 1; 2618 return (sysctl_lookup(SYSCTLFN_CALL(&node))); 2619} 2620 2621/* 2622 * sysctl helper routine for kern.consdev, dependent on the current 2623 * state of the console. also used for machdep.console_device on some 2624 * ports. 2625 */ 2626int 2627sysctl_consdev(SYSCTLFN_ARGS) 2628{ 2629 dev_t consdev; 2630 struct sysctlnode node; 2631 2632 if (cn_tab != NULL) 2633 consdev = cn_tab->cn_dev; 2634 else 2635 consdev = NODEV; 2636 node = *rnode; 2637 node.sysctl_data = &consdev; 2638 node.sysctl_size = sizeof(consdev); 2639 return (sysctl_lookup(SYSCTLFN_CALL(&node))); 2640} 2641 2642/* 2643 * ******************************************************************** 2644 * section 4: support for some helpers 2645 * ******************************************************************** 2646 */ 2647 2648/* 2649 * Fill in a kinfo_proc2 structure for the specified process. 2650 */ 2651static void 2652fill_kproc2(struct proc *p, struct kinfo_proc2 *ki) 2653{ 2654 struct tty *tp; 2655 struct lwp *l; 2656 struct timeval ut, st; 2657 2658 memset(ki, 0, sizeof(*ki)); 2659 2660 ki->p_paddr = PTRTOUINT64(p); 2661 ki->p_fd = PTRTOUINT64(p->p_fd); 2662 ki->p_cwdi = PTRTOUINT64(p->p_cwdi); 2663 ki->p_stats = PTRTOUINT64(p->p_stats); 2664 ki->p_limit = PTRTOUINT64(p->p_limit); 2665 ki->p_vmspace = PTRTOUINT64(p->p_vmspace); 2666 ki->p_sigacts = PTRTOUINT64(p->p_sigacts); 2667 ki->p_sess = PTRTOUINT64(p->p_session); 2668 ki->p_tsess = 0; /* may be changed if controlling tty below */ 2669 ki->p_ru = PTRTOUINT64(p->p_ru); 2670 2671 ki->p_eflag = 0; 2672 ki->p_exitsig = p->p_exitsig; 2673 ki->p_flag = p->p_flag; 2674 2675 ki->p_pid = p->p_pid; 2676 if (p->p_pptr) 2677 ki->p_ppid = p->p_pptr->p_pid; 2678 else 2679 ki->p_ppid = 0; 2680 ki->p_sid = p->p_session->s_sid; 2681 ki->p__pgid = p->p_pgrp->pg_id; 2682 2683 ki->p_tpgid = NO_PGID; /* may be changed if controlling tty below */ 2684 2685 ki->p_uid = kauth_cred_geteuid(p->p_cred); 2686 ki->p_ruid = kauth_cred_getuid(p->p_cred); 2687 ki->p_gid = kauth_cred_getegid(p->p_cred); 2688 ki->p_rgid = kauth_cred_getgid(p->p_cred); 2689 ki->p_svuid = kauth_cred_getsvuid(p->p_cred); 2690 ki->p_svgid = kauth_cred_getsvgid(p->p_cred); 2691 2692 ki->p_ngroups = kauth_cred_ngroups(p->p_cred); 2693 kauth_cred_getgroups(p->p_cred, ki->p_groups, 2694 min(ki->p_ngroups, sizeof(ki->p_groups) / sizeof(ki->p_groups[0]))); 2695 2696 ki->p_jobc = p->p_pgrp->pg_jobc; 2697 if ((p->p_flag & P_CONTROLT) && (tp = p->p_session->s_ttyp)) { 2698 ki->p_tdev = tp->t_dev; 2699 ki->p_tpgid = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PGID; 2700 ki->p_tsess = PTRTOUINT64(tp->t_session); 2701 } else { 2702 ki->p_tdev = NODEV; 2703 } 2704 2705 ki->p_estcpu = p->p_estcpu; 2706 ki->p_rtime_sec = p->p_rtime.tv_sec; 2707 ki->p_rtime_usec = p->p_rtime.tv_usec; 2708 ki->p_cpticks = p->p_cpticks; 2709 ki->p_pctcpu = p->p_pctcpu; 2710 2711 ki->p_uticks = p->p_uticks; 2712 ki->p_sticks = p->p_sticks; 2713 ki->p_iticks = p->p_iticks; 2714 2715 ki->p_tracep = PTRTOUINT64(p->p_tracep); 2716 ki->p_traceflag = p->p_traceflag; 2717 2718 2719 memcpy(&ki->p_siglist, &p->p_sigctx.ps_siglist, sizeof(ki_sigset_t)); 2720 memcpy(&ki->p_sigmask, &p->p_sigctx.ps_sigmask, sizeof(ki_sigset_t)); 2721 memcpy(&ki->p_sigignore, &p->p_sigctx.ps_sigignore,sizeof(ki_sigset_t)); 2722 memcpy(&ki->p_sigcatch, &p->p_sigctx.ps_sigcatch, sizeof(ki_sigset_t)); 2723 2724 ki->p_stat = p->p_stat; /* Will likely be overridden by LWP status */ 2725 ki->p_realstat = p->p_stat; 2726 ki->p_nice = p->p_nice; 2727 2728 ki->p_xstat = p->p_xstat; 2729 ki->p_acflag = p->p_acflag; 2730 2731 strncpy(ki->p_comm, p->p_comm, 2732 min(sizeof(ki->p_comm), sizeof(p->p_comm))); 2733 2734 strncpy(ki->p_login, p->p_session->s_login, 2735 min(sizeof ki->p_login - 1, sizeof p->p_session->s_login)); 2736 2737 ki->p_nlwps = p->p_nlwps; 2738 ki->p_nrlwps = p->p_nrlwps; 2739 ki->p_realflag = p->p_flag; 2740 2741 if (p->p_stat == SIDL || P_ZOMBIE(p)) { 2742 ki->p_vm_rssize = 0; 2743 ki->p_vm_tsize = 0; 2744 ki->p_vm_dsize = 0; 2745 ki->p_vm_ssize = 0; 2746 l = NULL; 2747 } else { 2748 struct vmspace *vm = p->p_vmspace; 2749 2750 ki->p_vm_rssize = vm_resident_count(vm); 2751 ki->p_vm_tsize = vm->vm_tsize; 2752 ki->p_vm_dsize = vm->vm_dsize; 2753 ki->p_vm_ssize = vm->vm_ssize; 2754 2755 /* Pick a "representative" LWP */ 2756 l = proc_representative_lwp(p); 2757 ki->p_forw = PTRTOUINT64(l->l_forw); 2758 ki->p_back = PTRTOUINT64(l->l_back); 2759 ki->p_addr = PTRTOUINT64(l->l_addr); 2760 ki->p_stat = l->l_stat; 2761 ki->p_flag |= l->l_flag & P_SHARED; 2762 ki->p_swtime = l->l_swtime; 2763 ki->p_slptime = l->l_slptime; 2764 if (l->l_stat == LSONPROC) { 2765 KDASSERT(l->l_cpu != NULL); 2766 ki->p_schedflags = l->l_cpu->ci_schedstate.spc_flags; 2767 } else 2768 ki->p_schedflags = 0; 2769 ki->p_holdcnt = l->l_holdcnt; 2770 ki->p_priority = l->l_priority; 2771 ki->p_usrpri = l->l_usrpri; 2772 if (l->l_wmesg) 2773 strncpy(ki->p_wmesg, l->l_wmesg, sizeof(ki->p_wmesg)); 2774 ki->p_wchan = PTRTOUINT64(l->l_wchan); 2775 2776 } 2777 2778 if (p->p_session->s_ttyvp) 2779 ki->p_eflag |= EPROC_CTTY; 2780 if (SESS_LEADER(p)) 2781 ki->p_eflag |= EPROC_SLEADER; 2782 2783 /* XXX Is this double check necessary? */ 2784 if (P_ZOMBIE(p)) { 2785 ki->p_uvalid = 0; 2786 } else { 2787 ki->p_uvalid = 1; 2788 2789 ki->p_ustart_sec = p->p_stats->p_start.tv_sec; 2790 ki->p_ustart_usec = p->p_stats->p_start.tv_usec; 2791 2792 calcru(p, &ut, &st, 0); 2793 ki->p_uutime_sec = ut.tv_sec; 2794 ki->p_uutime_usec = ut.tv_usec; 2795 ki->p_ustime_sec = st.tv_sec; 2796 ki->p_ustime_usec = st.tv_usec; 2797 2798 ki->p_uru_maxrss = p->p_stats->p_ru.ru_maxrss; 2799 ki->p_uru_ixrss = p->p_stats->p_ru.ru_ixrss; 2800 ki->p_uru_idrss = p->p_stats->p_ru.ru_idrss; 2801 ki->p_uru_isrss = p->p_stats->p_ru.ru_isrss; 2802 ki->p_uru_minflt = p->p_stats->p_ru.ru_minflt; 2803 ki->p_uru_majflt = p->p_stats->p_ru.ru_majflt; 2804 ki->p_uru_nswap = p->p_stats->p_ru.ru_nswap; 2805 ki->p_uru_inblock = p->p_stats->p_ru.ru_inblock; 2806 ki->p_uru_oublock = p->p_stats->p_ru.ru_oublock; 2807 ki->p_uru_msgsnd = p->p_stats->p_ru.ru_msgsnd; 2808 ki->p_uru_msgrcv = p->p_stats->p_ru.ru_msgrcv; 2809 ki->p_uru_nsignals = p->p_stats->p_ru.ru_nsignals; 2810 ki->p_uru_nvcsw = p->p_stats->p_ru.ru_nvcsw; 2811 ki->p_uru_nivcsw = p->p_stats->p_ru.ru_nivcsw; 2812 2813 timeradd(&p->p_stats->p_cru.ru_utime, 2814 &p->p_stats->p_cru.ru_stime, &ut); 2815 ki->p_uctime_sec = ut.tv_sec; 2816 ki->p_uctime_usec = ut.tv_usec; 2817 } 2818#ifdef MULTIPROCESSOR 2819 if (l && l->l_cpu != NULL) 2820 ki->p_cpuid = l->l_cpu->ci_cpuid; 2821 else 2822#endif 2823 ki->p_cpuid = KI_NOCPU; 2824} 2825 2826/* 2827 * Fill in a kinfo_lwp structure for the specified lwp. 2828 */ 2829static void 2830fill_lwp(struct lwp *l, struct kinfo_lwp *kl) 2831{ 2832 2833 kl->l_forw = PTRTOUINT64(l->l_forw); 2834 kl->l_back = PTRTOUINT64(l->l_back); 2835 kl->l_laddr = PTRTOUINT64(l); 2836 kl->l_addr = PTRTOUINT64(l->l_addr); 2837 kl->l_stat = l->l_stat; 2838 kl->l_lid = l->l_lid; 2839 kl->l_flag = l->l_flag; 2840 2841 kl->l_swtime = l->l_swtime; 2842 kl->l_slptime = l->l_slptime; 2843 if (l->l_stat == LSONPROC) { 2844 KDASSERT(l->l_cpu != NULL); 2845 kl->l_schedflags = l->l_cpu->ci_schedstate.spc_flags; 2846 } else 2847 kl->l_schedflags = 0; 2848 kl->l_holdcnt = l->l_holdcnt; 2849 kl->l_priority = l->l_priority; 2850 kl->l_usrpri = l->l_usrpri; 2851 if (l->l_wmesg) 2852 strncpy(kl->l_wmesg, l->l_wmesg, sizeof(kl->l_wmesg)); 2853 kl->l_wchan = PTRTOUINT64(l->l_wchan); 2854#ifdef MULTIPROCESSOR 2855 if (l->l_cpu != NULL) 2856 kl->l_cpuid = l->l_cpu->ci_cpuid; 2857 else 2858#endif 2859 kl->l_cpuid = KI_NOCPU; 2860} 2861 2862/* 2863 * Fill in an eproc structure for the specified process. 2864 */ 2865void 2866fill_eproc(struct proc *p, struct eproc *ep) 2867{ 2868 struct tty *tp; 2869 struct lwp *l; 2870 2871 ep->e_paddr = p; 2872 ep->e_sess = p->p_session; 2873 kauth_cred_topcred(p->p_cred, &ep->e_pcred); 2874 kauth_cred_toucred(p->p_cred, &ep->e_ucred); 2875 if (p->p_stat == SIDL || P_ZOMBIE(p)) { 2876 ep->e_vm.vm_rssize = 0; 2877 ep->e_vm.vm_tsize = 0; 2878 ep->e_vm.vm_dsize = 0; 2879 ep->e_vm.vm_ssize = 0; 2880 /* ep->e_vm.vm_pmap = XXX; */ 2881 } else { 2882 struct vmspace *vm = p->p_vmspace; 2883 2884 ep->e_vm.vm_rssize = vm_resident_count(vm); 2885 ep->e_vm.vm_tsize = vm->vm_tsize; 2886 ep->e_vm.vm_dsize = vm->vm_dsize; 2887 ep->e_vm.vm_ssize = vm->vm_ssize; 2888 2889 /* Pick a "representative" LWP */ 2890 l = proc_representative_lwp(p); 2891 2892 if (l->l_wmesg) 2893 strncpy(ep->e_wmesg, l->l_wmesg, WMESGLEN); 2894 } 2895 if (p->p_pptr) 2896 ep->e_ppid = p->p_pptr->p_pid; 2897 else 2898 ep->e_ppid = 0; 2899 ep->e_pgid = p->p_pgrp->pg_id; 2900 ep->e_sid = ep->e_sess->s_sid; 2901 ep->e_jobc = p->p_pgrp->pg_jobc; 2902 if ((p->p_flag & P_CONTROLT) && 2903 (tp = ep->e_sess->s_ttyp)) { 2904 ep->e_tdev = tp->t_dev; 2905 ep->e_tpgid = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PGID; 2906 ep->e_tsess = tp->t_session; 2907 } else 2908 ep->e_tdev = NODEV; 2909 2910 ep->e_xsize = ep->e_xrssize = 0; 2911 ep->e_xccount = ep->e_xswrss = 0; 2912 ep->e_flag = ep->e_sess->s_ttyvp ? EPROC_CTTY : 0; 2913 if (SESS_LEADER(p)) 2914 ep->e_flag |= EPROC_SLEADER; 2915 strncpy(ep->e_login, ep->e_sess->s_login, MAXLOGNAME); 2916} 2917