init_sysctl.c revision 1.224
1/* $NetBSD: init_sysctl.c,v 1.224 2020/01/18 14:40:03 skrll Exp $ */ 2 3/*- 4 * Copyright (c) 2003, 2007, 2008, 2009 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, and by Andrew Doran. 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 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32#include <sys/cdefs.h> 33__KERNEL_RCSID(0, "$NetBSD: init_sysctl.c,v 1.224 2020/01/18 14:40:03 skrll Exp $"); 34 35#include "opt_sysv.h" 36#include "opt_compat_netbsd.h" 37#include "opt_modular.h" 38#include "opt_gprof.h" 39#include "pty.h" 40 41#include <sys/types.h> 42#include <sys/param.h> 43#include <sys/sysctl.h> 44#include <sys/cpu.h> 45#include <sys/errno.h> 46#include <sys/systm.h> 47#include <sys/kernel.h> 48#include <sys/unistd.h> 49#include <sys/disklabel.h> 50#include <sys/cprng.h> 51#include <sys/vnode_impl.h> /* For vfs_drainvnodes(). */ 52#include <sys/mount.h> 53#include <sys/namei.h> 54#include <dev/cons.h> 55#include <sys/socketvar.h> 56#include <sys/file.h> 57#include <sys/filedesc.h> 58#include <sys/tty.h> 59#include <sys/kmem.h> 60#include <sys/reboot.h> 61#include <sys/resource.h> 62#include <sys/resourcevar.h> 63#include <sys/exec.h> 64#include <sys/conf.h> 65#include <sys/device.h> 66#include <sys/stat.h> 67#include <sys/kauth.h> 68#include <sys/ktrace.h> 69 70#include <sys/cpu.h> 71 72int security_setidcore_dump; 73char security_setidcore_path[MAXPATHLEN] = "/var/crash/%n.core"; 74uid_t security_setidcore_owner = 0; 75gid_t security_setidcore_group = 0; 76mode_t security_setidcore_mode = (S_IRUSR|S_IWUSR); 77 78/* 79 * Current status of SysV IPC capability. Initially, these are 80 * 0 if the capability is not built-in to the kernel, but can 81 * be updated if the appropriate kernel module is (auto)loaded. 82 */ 83 84int kern_has_sysvmsg = 0; 85int kern_has_sysvshm = 0; 86int kern_has_sysvsem = 0; 87 88static const u_int sysctl_lwpprflagmap[] = { 89 LPR_DETACHED, L_DETACHED, 90 0 91}; 92 93/* 94 * try over estimating by 5 procs/lwps 95 */ 96#define KERN_LWPSLOP (5 * sizeof(struct kinfo_lwp)) 97 98static int dcopyout(struct lwp *, const void *, void *, size_t); 99 100static int 101dcopyout(struct lwp *l, const void *kaddr, void *uaddr, size_t len) 102{ 103 int error; 104 105 error = copyout(kaddr, uaddr, len); 106 ktrmibio(-1, UIO_READ, uaddr, len, error); 107 108 return error; 109} 110 111static int sysctl_kern_maxvnodes(SYSCTLFN_PROTO); 112static int sysctl_kern_messages(SYSCTLFN_PROTO); 113static int sysctl_kern_boottime(SYSCTLFN_PROTO); 114static int sysctl_kern_rtc_offset(SYSCTLFN_PROTO); 115static int sysctl_kern_maxproc(SYSCTLFN_PROTO); 116static int sysctl_kern_hostid(SYSCTLFN_PROTO); 117static int sysctl_kern_defcorename(SYSCTLFN_PROTO); 118static int sysctl_kern_cptime(SYSCTLFN_PROTO); 119#if NPTY > 0 120static int sysctl_kern_maxptys(SYSCTLFN_PROTO); 121#endif /* NPTY > 0 */ 122static int sysctl_kern_lwp(SYSCTLFN_PROTO); 123static int sysctl_kern_forkfsleep(SYSCTLFN_PROTO); 124static int sysctl_kern_root_partition(SYSCTLFN_PROTO); 125static int sysctl_kern_drivers(SYSCTLFN_PROTO); 126static int sysctl_security_setidcore(SYSCTLFN_PROTO); 127static int sysctl_security_setidcorename(SYSCTLFN_PROTO); 128static int sysctl_kern_cpid(SYSCTLFN_PROTO); 129static int sysctl_hw_usermem(SYSCTLFN_PROTO); 130static int sysctl_hw_cnmagic(SYSCTLFN_PROTO); 131 132static void fill_lwp(struct lwp *l, struct kinfo_lwp *kl); 133 134/* 135 * ******************************************************************** 136 * section 1: setup routines 137 * ******************************************************************** 138 * These functions are stuffed into a link set for sysctl setup 139 * functions. They're never called or referenced from anywhere else. 140 * ******************************************************************** 141 */ 142 143/* 144 * this setup routine is a replacement for kern_sysctl() 145 */ 146SYSCTL_SETUP(sysctl_kern_setup, "sysctl kern subtree setup") 147{ 148 extern int kern_logsigexit; /* defined in kern/kern_sig.c */ 149 extern fixpt_t ccpu; /* defined in kern/kern_synch.c */ 150 extern int dumponpanic; /* defined in kern/subr_prf.c */ 151 const struct sysctlnode *rnode; 152 153 sysctl_createv(clog, 0, NULL, NULL, 154 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 155 CTLTYPE_INT, "maxvnodes", 156 SYSCTL_DESCR("Maximum number of vnodes"), 157 sysctl_kern_maxvnodes, 0, NULL, 0, 158 CTL_KERN, KERN_MAXVNODES, CTL_EOL); 159 sysctl_createv(clog, 0, NULL, NULL, 160 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 161 CTLTYPE_INT, "maxproc", 162 SYSCTL_DESCR("Maximum number of simultaneous processes"), 163 sysctl_kern_maxproc, 0, NULL, 0, 164 CTL_KERN, KERN_MAXPROC, CTL_EOL); 165 sysctl_createv(clog, 0, NULL, NULL, 166 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 167 CTLTYPE_INT, "maxfiles", 168 SYSCTL_DESCR("Maximum number of open files"), 169 NULL, 0, &maxfiles, 0, 170 CTL_KERN, KERN_MAXFILES, CTL_EOL); 171 sysctl_createv(clog, 0, NULL, NULL, 172 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 173 CTLTYPE_INT, "argmax", 174 SYSCTL_DESCR("Maximum number of bytes of arguments to " 175 "execve(2)"), 176 NULL, ARG_MAX, NULL, 0, 177 CTL_KERN, KERN_ARGMAX, CTL_EOL); 178 sysctl_createv(clog, 0, NULL, NULL, 179 CTLFLAG_PERMANENT|CTLFLAG_READWRITE|CTLFLAG_HEX, 180 CTLTYPE_INT, "hostid", 181 SYSCTL_DESCR("System host ID number"), 182 sysctl_kern_hostid, 0, NULL, 0, 183 CTL_KERN, KERN_HOSTID, CTL_EOL); 184 sysctl_createv(clog, 0, NULL, NULL, 185 CTLFLAG_PERMANENT, 186 CTLTYPE_STRUCT, "vnode", 187 SYSCTL_DESCR("System vnode table"), 188 sysctl_kern_vnode, 0, NULL, 0, 189 CTL_KERN, KERN_VNODE, CTL_EOL); 190#ifndef GPROF 191 sysctl_createv(clog, 0, NULL, NULL, 192 CTLFLAG_PERMANENT, 193 CTLTYPE_NODE, "profiling", 194 SYSCTL_DESCR("Profiling information (not available)"), 195 sysctl_notavail, 0, NULL, 0, 196 CTL_KERN, KERN_PROF, CTL_EOL); 197#endif 198 sysctl_createv(clog, 0, NULL, NULL, 199 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 200 CTLTYPE_INT, "posix1version", 201 SYSCTL_DESCR("Version of ISO/IEC 9945 (POSIX 1003.1) " 202 "with which the operating system attempts " 203 "to comply"), 204 NULL, _POSIX_VERSION, NULL, 0, 205 CTL_KERN, KERN_POSIX1, CTL_EOL); 206 sysctl_createv(clog, 0, NULL, NULL, 207 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 208 CTLTYPE_INT, "ngroups", 209 SYSCTL_DESCR("Maximum number of supplemental groups"), 210 NULL, NGROUPS_MAX, NULL, 0, 211 CTL_KERN, KERN_NGROUPS, CTL_EOL); 212 sysctl_createv(clog, 0, NULL, NULL, 213 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 214 CTLTYPE_INT, "job_control", 215 SYSCTL_DESCR("Whether job control is available"), 216 NULL, 1, NULL, 0, 217 CTL_KERN, KERN_JOB_CONTROL, CTL_EOL); 218 sysctl_createv(clog, 0, NULL, NULL, 219 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 220 CTLTYPE_INT, "saved_ids", 221 SYSCTL_DESCR("Whether POSIX saved set-group/user ID is " 222 "available"), NULL, 223#ifdef _POSIX_SAVED_IDS 224 1, 225#else /* _POSIX_SAVED_IDS */ 226 0, 227#endif /* _POSIX_SAVED_IDS */ 228 NULL, 0, CTL_KERN, KERN_SAVED_IDS, CTL_EOL); 229 sysctl_createv(clog, 0, NULL, NULL, 230 CTLFLAG_PERMANENT|CTLFLAG_HEX, 231 CTLTYPE_INT, "boothowto", 232 SYSCTL_DESCR("Flags from boot loader"), 233 NULL, 0, &boothowto, sizeof(boothowto), 234 CTL_KERN, CTL_CREATE, CTL_EOL); 235 sysctl_createv(clog, 0, NULL, NULL, 236 CTLFLAG_PERMANENT, 237 CTLTYPE_STRUCT, "boottime", 238 SYSCTL_DESCR("System boot time"), 239 sysctl_kern_boottime, 0, NULL, sizeof(struct timespec), 240 CTL_KERN, KERN_BOOTTIME, CTL_EOL); 241 sysctl_createv(clog, 0, NULL, NULL, 242 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 243 CTLTYPE_INT, "maxpartitions", 244 SYSCTL_DESCR("Maximum number of partitions allowed per " 245 "disk"), 246 NULL, MAXPARTITIONS, NULL, 0, 247 CTL_KERN, KERN_MAXPARTITIONS, CTL_EOL); 248 sysctl_createv(clog, 0, NULL, NULL, 249 CTLFLAG_PERMANENT, 250 CTLTYPE_STRUCT, "timex", NULL, 251 sysctl_notavail, 0, NULL, 0, 252 CTL_KERN, KERN_TIMEX, CTL_EOL); 253 sysctl_createv(clog, 0, NULL, NULL, 254 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 255 CTLTYPE_INT, "rtc_offset", 256 SYSCTL_DESCR("Offset of real time clock from UTC in " 257 "minutes"), 258 sysctl_kern_rtc_offset, 0, &rtc_offset, 0, 259 CTL_KERN, KERN_RTC_OFFSET, CTL_EOL); 260 sysctl_createv(clog, 0, NULL, NULL, 261 CTLFLAG_PERMANENT, 262 CTLTYPE_STRING, "root_device", 263 SYSCTL_DESCR("Name of the root device"), 264 sysctl_root_device, 0, NULL, 0, 265 CTL_KERN, KERN_ROOT_DEVICE, CTL_EOL); 266 sysctl_createv(clog, 0, NULL, NULL, 267 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 268 CTLTYPE_INT, "fsync", 269 SYSCTL_DESCR("Whether the POSIX 1003.1b File " 270 "Synchronization Option is available on " 271 "this system"), 272 NULL, 1, NULL, 0, 273 CTL_KERN, KERN_FSYNC, CTL_EOL); 274 sysctl_createv(clog, 0, NULL, NULL, 275 CTLFLAG_PERMANENT, 276 CTLTYPE_NODE, "ipc", 277 SYSCTL_DESCR("SysV IPC options"), 278 NULL, 0, NULL, 0, 279 CTL_KERN, KERN_SYSVIPC, CTL_EOL); 280 sysctl_createv(clog, 0, NULL, NULL, 281 CTLFLAG_PERMANENT|CTLFLAG_READONLY, 282 CTLTYPE_INT, "sysvmsg", 283 SYSCTL_DESCR("System V style message support available"), 284 NULL, 0, &kern_has_sysvmsg, sizeof(int), 285 CTL_KERN, KERN_SYSVIPC, KERN_SYSVIPC_MSG, CTL_EOL); 286 sysctl_createv(clog, 0, NULL, NULL, 287 CTLFLAG_PERMANENT|CTLFLAG_READONLY, 288 CTLTYPE_INT, "sysvsem", 289 SYSCTL_DESCR("System V style semaphore support " 290 "available"), 291 NULL, 0, &kern_has_sysvsem, sizeof(int), 292 CTL_KERN, KERN_SYSVIPC, KERN_SYSVIPC_SEM, CTL_EOL); 293 sysctl_createv(clog, 0, NULL, NULL, 294 CTLFLAG_PERMANENT|CTLFLAG_READONLY, 295 CTLTYPE_INT, "sysvshm", 296 SYSCTL_DESCR("System V style shared memory support " 297 "available"), 298 NULL, 0, &kern_has_sysvshm, sizeof(int), 299 CTL_KERN, KERN_SYSVIPC, KERN_SYSVIPC_SHM, CTL_EOL); 300 sysctl_createv(clog, 0, NULL, NULL, 301 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 302 CTLTYPE_INT, "synchronized_io", 303 SYSCTL_DESCR("Whether the POSIX 1003.1b Synchronized " 304 "I/O Option is available on this system"), 305 NULL, 1, NULL, 0, 306 CTL_KERN, KERN_SYNCHRONIZED_IO, CTL_EOL); 307 sysctl_createv(clog, 0, NULL, NULL, 308 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 309 CTLTYPE_INT, "iov_max", 310 SYSCTL_DESCR("Maximum number of iovec structures per " 311 "process"), 312 NULL, IOV_MAX, NULL, 0, 313 CTL_KERN, KERN_IOV_MAX, CTL_EOL); 314 sysctl_createv(clog, 0, NULL, NULL, 315 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 316 CTLTYPE_INT, "mapped_files", 317 SYSCTL_DESCR("Whether the POSIX 1003.1b Memory Mapped " 318 "Files Option is available on this system"), 319 NULL, 1, NULL, 0, 320 CTL_KERN, KERN_MAPPED_FILES, CTL_EOL); 321 sysctl_createv(clog, 0, NULL, NULL, 322 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 323 CTLTYPE_INT, "memlock", 324 SYSCTL_DESCR("Whether the POSIX 1003.1b Process Memory " 325 "Locking Option is available on this " 326 "system"), 327 NULL, 1, NULL, 0, 328 CTL_KERN, KERN_MEMLOCK, CTL_EOL); 329 sysctl_createv(clog, 0, NULL, NULL, 330 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 331 CTLTYPE_INT, "memlock_range", 332 SYSCTL_DESCR("Whether the POSIX 1003.1b Range Memory " 333 "Locking Option is available on this " 334 "system"), 335 NULL, 1, NULL, 0, 336 CTL_KERN, KERN_MEMLOCK_RANGE, CTL_EOL); 337 sysctl_createv(clog, 0, NULL, NULL, 338 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 339 CTLTYPE_INT, "memory_protection", 340 SYSCTL_DESCR("Whether the POSIX 1003.1b Memory " 341 "Protection Option is available on this " 342 "system"), 343 NULL, 1, NULL, 0, 344 CTL_KERN, KERN_MEMORY_PROTECTION, CTL_EOL); 345 sysctl_createv(clog, 0, NULL, NULL, 346 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 347 CTLTYPE_INT, "login_name_max", 348 SYSCTL_DESCR("Maximum login name length"), 349 NULL, LOGIN_NAME_MAX, NULL, 0, 350 CTL_KERN, KERN_LOGIN_NAME_MAX, CTL_EOL); 351 sysctl_createv(clog, 0, NULL, NULL, 352 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 353 CTLTYPE_STRING, "defcorename", 354 SYSCTL_DESCR("Default core file name"), 355 sysctl_kern_defcorename, 0, defcorename, MAXPATHLEN, 356 CTL_KERN, KERN_DEFCORENAME, CTL_EOL); 357 sysctl_createv(clog, 0, NULL, NULL, 358 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 359 CTLTYPE_INT, "logsigexit", 360 SYSCTL_DESCR("Log process exit when caused by signals"), 361 NULL, 0, &kern_logsigexit, 0, 362 CTL_KERN, KERN_LOGSIGEXIT, CTL_EOL); 363 sysctl_createv(clog, 0, NULL, NULL, 364 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 365 CTLTYPE_INT, "fscale", 366 SYSCTL_DESCR("Kernel fixed-point scale factor"), 367 NULL, FSCALE, NULL, 0, 368 CTL_KERN, KERN_FSCALE, CTL_EOL); 369 sysctl_createv(clog, 0, NULL, NULL, 370 CTLFLAG_PERMANENT, 371 CTLTYPE_INT, "ccpu", 372 SYSCTL_DESCR("Scheduler exponential decay value"), 373 NULL, 0, &ccpu, 0, 374 CTL_KERN, KERN_CCPU, CTL_EOL); 375 sysctl_createv(clog, 0, NULL, NULL, 376 CTLFLAG_PERMANENT, 377 CTLTYPE_STRUCT, "cp_time", 378 SYSCTL_DESCR("Clock ticks spent in different CPU states"), 379 sysctl_kern_cptime, 0, NULL, 0, 380 CTL_KERN, KERN_CP_TIME, CTL_EOL); 381 sysctl_createv(clog, 0, NULL, NULL, 382 CTLFLAG_PERMANENT, 383 CTLTYPE_STRUCT, "consdev", 384 SYSCTL_DESCR("Console device"), 385 sysctl_consdev, 0, NULL, sizeof(dev_t), 386 CTL_KERN, KERN_CONSDEV, CTL_EOL); 387#if NPTY > 0 388 sysctl_createv(clog, 0, NULL, NULL, 389 CTLFLAG_PERMANENT, 390 CTLTYPE_INT, "maxptys", 391 SYSCTL_DESCR("Maximum number of pseudo-ttys"), 392 sysctl_kern_maxptys, 0, NULL, 0, 393 CTL_KERN, KERN_MAXPTYS, CTL_EOL); 394#endif /* NPTY > 0 */ 395 sysctl_createv(clog, 0, NULL, NULL, 396 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 397 CTLTYPE_INT, "maxphys", 398 SYSCTL_DESCR("Maximum raw I/O transfer size"), 399 NULL, MAXPHYS, NULL, 0, 400 CTL_KERN, KERN_MAXPHYS, CTL_EOL); 401 sysctl_createv(clog, 0, NULL, NULL, 402 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 403 CTLTYPE_INT, "monotonic_clock", 404 SYSCTL_DESCR("Implementation version of the POSIX " 405 "1003.1b Monotonic Clock Option"), 406 /* XXX _POSIX_VERSION */ 407 NULL, _POSIX_MONOTONIC_CLOCK, NULL, 0, 408 CTL_KERN, KERN_MONOTONIC_CLOCK, CTL_EOL); 409 sysctl_createv(clog, 0, NULL, NULL, 410 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 411 CTLTYPE_INT, "labelsector", 412 SYSCTL_DESCR("Sector number containing the disklabel"), 413 NULL, LABELSECTOR, NULL, 0, 414 CTL_KERN, KERN_LABELSECTOR, CTL_EOL); 415 sysctl_createv(clog, 0, NULL, NULL, 416 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 417 CTLTYPE_INT, "labeloffset", 418 SYSCTL_DESCR("Offset of the disklabel within the " 419 "sector"), 420 NULL, LABELOFFSET, NULL, 0, 421 CTL_KERN, KERN_LABELOFFSET, CTL_EOL); 422 sysctl_createv(clog, 0, NULL, NULL, 423 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 424 CTLTYPE_INT, "labelusesmbr", 425 SYSCTL_DESCR("disklabel is inside MBR partition"), 426 NULL, LABELUSESMBR, NULL, 0, 427 CTL_KERN, CTL_CREATE, CTL_EOL); 428 sysctl_createv(clog, 0, NULL, NULL, 429 CTLFLAG_PERMANENT, 430 CTLTYPE_NODE, "lwp", 431 SYSCTL_DESCR("System-wide LWP information"), 432 sysctl_kern_lwp, 0, NULL, 0, 433 CTL_KERN, KERN_LWP, CTL_EOL); 434 sysctl_createv(clog, 0, NULL, NULL, 435 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 436 CTLTYPE_INT, "forkfsleep", 437 SYSCTL_DESCR("Milliseconds to sleep on fork failure due " 438 "to process limits"), 439 sysctl_kern_forkfsleep, 0, NULL, 0, 440 CTL_KERN, KERN_FORKFSLEEP, CTL_EOL); 441 sysctl_createv(clog, 0, NULL, NULL, 442 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 443 CTLTYPE_INT, "posix_threads", 444 SYSCTL_DESCR("Version of IEEE Std 1003.1 and its " 445 "Threads option to which the system " 446 "attempts to conform"), 447 /* XXX _POSIX_VERSION */ 448 NULL, _POSIX_THREADS, NULL, 0, 449 CTL_KERN, KERN_POSIX_THREADS, CTL_EOL); 450 sysctl_createv(clog, 0, NULL, NULL, 451 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 452 CTLTYPE_INT, "posix_semaphores", 453 SYSCTL_DESCR("Version of IEEE Std 1003.1 and its " 454 "Semaphores option to which the system " 455 "attempts to conform"), NULL, 456 200112, NULL, 0, 457 CTL_KERN, KERN_POSIX_SEMAPHORES, CTL_EOL); 458 sysctl_createv(clog, 0, NULL, NULL, 459 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 460 CTLTYPE_INT, "posix_barriers", 461 SYSCTL_DESCR("Version of IEEE Std 1003.1 and its " 462 "Barriers option to which the system " 463 "attempts to conform"), 464 /* XXX _POSIX_VERSION */ 465 NULL, _POSIX_BARRIERS, NULL, 0, 466 CTL_KERN, KERN_POSIX_BARRIERS, CTL_EOL); 467 sysctl_createv(clog, 0, NULL, NULL, 468 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 469 CTLTYPE_INT, "posix_timers", 470 SYSCTL_DESCR("Version of IEEE Std 1003.1 and its " 471 "Timers option to which the system " 472 "attempts to conform"), 473 /* XXX _POSIX_VERSION */ 474 NULL, _POSIX_TIMERS, NULL, 0, 475 CTL_KERN, KERN_POSIX_TIMERS, CTL_EOL); 476 sysctl_createv(clog, 0, NULL, NULL, 477 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 478 CTLTYPE_INT, "posix_spin_locks", 479 SYSCTL_DESCR("Version of IEEE Std 1003.1 and its Spin " 480 "Locks option to which the system attempts " 481 "to conform"), 482 /* XXX _POSIX_VERSION */ 483 NULL, _POSIX_SPIN_LOCKS, NULL, 0, 484 CTL_KERN, KERN_POSIX_SPIN_LOCKS, CTL_EOL); 485 sysctl_createv(clog, 0, NULL, NULL, 486 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 487 CTLTYPE_INT, "posix_reader_writer_locks", 488 SYSCTL_DESCR("Version of IEEE Std 1003.1 and its " 489 "Read-Write Locks option to which the " 490 "system attempts to conform"), 491 /* XXX _POSIX_VERSION */ 492 NULL, _POSIX_READER_WRITER_LOCKS, NULL, 0, 493 CTL_KERN, KERN_POSIX_READER_WRITER_LOCKS, CTL_EOL); 494 sysctl_createv(clog, 0, NULL, NULL, 495 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 496 CTLTYPE_INT, "dump_on_panic", 497 SYSCTL_DESCR("Perform a crash dump on system panic"), 498 NULL, 0, &dumponpanic, 0, 499 CTL_KERN, KERN_DUMP_ON_PANIC, CTL_EOL); 500 sysctl_createv(clog, 0, NULL, NULL, 501 CTLFLAG_PERMANENT, 502 CTLTYPE_INT, "root_partition", 503 SYSCTL_DESCR("Root partition on the root device"), 504 sysctl_kern_root_partition, 0, NULL, 0, 505 CTL_KERN, KERN_ROOT_PARTITION, CTL_EOL); 506 sysctl_createv(clog, 0, NULL, NULL, 507 CTLFLAG_PERMANENT, 508 CTLTYPE_STRUCT, "drivers", 509 SYSCTL_DESCR("List of all drivers with block and " 510 "character device numbers"), 511 sysctl_kern_drivers, 0, NULL, 0, 512 CTL_KERN, KERN_DRIVERS, CTL_EOL); 513 sysctl_createv(clog, 0, NULL, NULL, 514 CTLFLAG_PERMANENT, 515 CTLTYPE_STRUCT, "cp_id", 516 SYSCTL_DESCR("Mapping of CPU number to CPU id"), 517 sysctl_kern_cpid, 0, NULL, 0, 518 CTL_KERN, KERN_CP_ID, CTL_EOL); 519 sysctl_createv(clog, 0, NULL, &rnode, 520 CTLFLAG_PERMANENT, 521 CTLTYPE_NODE, "coredump", 522 SYSCTL_DESCR("Coredump settings."), 523 NULL, 0, NULL, 0, 524 CTL_KERN, CTL_CREATE, CTL_EOL); 525 sysctl_createv(clog, 0, &rnode, &rnode, 526 CTLFLAG_PERMANENT, 527 CTLTYPE_NODE, "setid", 528 SYSCTL_DESCR("Set-id processes' coredump settings."), 529 NULL, 0, NULL, 0, 530 CTL_CREATE, CTL_EOL); 531 sysctl_createv(clog, 0, &rnode, NULL, 532 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 533 CTLTYPE_INT, "dump", 534 SYSCTL_DESCR("Allow set-id processes to dump core."), 535 sysctl_security_setidcore, 0, &security_setidcore_dump, 536 sizeof(security_setidcore_dump), 537 CTL_CREATE, CTL_EOL); 538 sysctl_createv(clog, 0, &rnode, NULL, 539 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 540 CTLTYPE_STRING, "path", 541 SYSCTL_DESCR("Path pattern for set-id coredumps."), 542 sysctl_security_setidcorename, 0, 543 security_setidcore_path, 544 sizeof(security_setidcore_path), 545 CTL_CREATE, CTL_EOL); 546 sysctl_createv(clog, 0, &rnode, NULL, 547 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 548 CTLTYPE_INT, "owner", 549 SYSCTL_DESCR("Owner id for set-id processes' cores."), 550 sysctl_security_setidcore, 0, &security_setidcore_owner, 551 0, 552 CTL_CREATE, CTL_EOL); 553 sysctl_createv(clog, 0, &rnode, NULL, 554 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 555 CTLTYPE_INT, "group", 556 SYSCTL_DESCR("Group id for set-id processes' cores."), 557 sysctl_security_setidcore, 0, &security_setidcore_group, 558 0, 559 CTL_CREATE, CTL_EOL); 560 sysctl_createv(clog, 0, &rnode, NULL, 561 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 562 CTLTYPE_INT, "mode", 563 SYSCTL_DESCR("Mode for set-id processes' cores."), 564 sysctl_security_setidcore, 0, &security_setidcore_mode, 565 0, 566 CTL_CREATE, CTL_EOL); 567 sysctl_createv(clog, 0, NULL, NULL, 568 CTLFLAG_IMMEDIATE|CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 569 CTLTYPE_INT, "no_sa_support", 570 SYSCTL_DESCR("0 if the kernel supports SA, otherwise " 571 "it doesn't"), 572 NULL, 1, NULL, 0, 573 CTL_KERN, CTL_CREATE, CTL_EOL); 574 sysctl_createv(clog, 0, NULL, NULL, 575 CTLFLAG_PERMANENT, 576 CTLTYPE_STRING, "configname", 577 SYSCTL_DESCR("Name of config file"), 578 NULL, 0, __UNCONST(kernel_ident), 0, 579 CTL_KERN, CTL_CREATE, CTL_EOL); 580 sysctl_createv(clog, 0, NULL, NULL, 581 CTLFLAG_PERMANENT, 582 CTLTYPE_STRING, "buildinfo", 583 SYSCTL_DESCR("Information from build environment"), 584 NULL, 0, __UNCONST(buildinfo), 0, 585 CTL_KERN, CTL_CREATE, CTL_EOL); 586 sysctl_createv(clog, 0, NULL, NULL, 587 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 588 CTLTYPE_INT, "messages", 589 SYSCTL_DESCR("Kernel message verbosity"), 590 sysctl_kern_messages, 0, NULL, 0, 591 CTL_KERN, CTL_CREATE, CTL_EOL); 592} 593 594SYSCTL_SETUP(sysctl_hw_misc_setup, "sysctl hw subtree misc setup") 595{ 596 597 sysctl_createv(clog, 0, NULL, NULL, 598 CTLFLAG_PERMANENT, 599 CTLTYPE_INT, "usermem", 600 SYSCTL_DESCR("Bytes of non-kernel memory"), 601 sysctl_hw_usermem, 0, NULL, 0, 602 CTL_HW, HW_USERMEM, CTL_EOL); 603 sysctl_createv(clog, 0, NULL, NULL, 604 CTLFLAG_PERMANENT|CTLFLAG_READWRITE|CTLFLAG_HEX, 605 CTLTYPE_STRING, "cnmagic", 606 SYSCTL_DESCR("Console magic key sequence"), 607 sysctl_hw_cnmagic, 0, NULL, CNS_LEN, 608 CTL_HW, HW_CNMAGIC, CTL_EOL); 609 sysctl_createv(clog, 0, NULL, NULL, 610 CTLFLAG_PERMANENT, 611 CTLTYPE_QUAD, "usermem64", 612 SYSCTL_DESCR("Bytes of non-kernel memory"), 613 sysctl_hw_usermem, 0, NULL, 0, 614 CTL_HW, HW_USERMEM64, CTL_EOL); 615} 616 617#ifdef DEBUG 618/* 619 * Debugging related system variables. 620 */ 621struct ctldebug /* debug0, */ /* debug1, */ debug2, debug3, debug4; 622struct ctldebug debug5, debug6, debug7, debug8, debug9; 623struct ctldebug debug10, debug11, debug12, debug13, debug14; 624struct ctldebug debug15, debug16, debug17, debug18, debug19; 625static struct ctldebug *debugvars[] = { 626 &debug0, &debug1, &debug2, &debug3, &debug4, 627 &debug5, &debug6, &debug7, &debug8, &debug9, 628 &debug10, &debug11, &debug12, &debug13, &debug14, 629 &debug15, &debug16, &debug17, &debug18, &debug19, 630}; 631 632/* 633 * this setup routine is a replacement for debug_sysctl() 634 * 635 * note that it creates several nodes per defined debug variable 636 */ 637SYSCTL_SETUP(sysctl_debug_setup, "sysctl debug subtree setup") 638{ 639 struct ctldebug *cdp; 640 char nodename[20]; 641 int i; 642 643 /* 644 * two ways here: 645 * 646 * the "old" way (debug.name -> value) which was emulated by 647 * the sysctl(8) binary 648 * 649 * the new way, which the sysctl(8) binary was actually using 650 651 node debug 652 node debug.0 653 string debug.0.name 654 int debug.0.value 655 int debug.name 656 657 */ 658 659 for (i = 0; i < __arraycount(debugvars); i++) { 660 cdp = debugvars[i]; 661 if (cdp->debugname == NULL || cdp->debugvar == NULL) 662 continue; 663 664 snprintf(nodename, sizeof(nodename), "debug%d", i); 665 sysctl_createv(clog, 0, NULL, NULL, 666 CTLFLAG_PERMANENT|CTLFLAG_HIDDEN, 667 CTLTYPE_NODE, nodename, NULL, 668 NULL, 0, NULL, 0, 669 CTL_DEBUG, i, CTL_EOL); 670 sysctl_createv(clog, 0, NULL, NULL, 671 CTLFLAG_PERMANENT|CTLFLAG_HIDDEN, 672 CTLTYPE_STRING, "name", NULL, 673 /*XXXUNCONST*/ 674 NULL, 0, __UNCONST(cdp->debugname), 0, 675 CTL_DEBUG, i, CTL_DEBUG_NAME, CTL_EOL); 676 sysctl_createv(clog, 0, NULL, NULL, 677 CTLFLAG_PERMANENT|CTLFLAG_HIDDEN, 678 CTLTYPE_INT, "value", NULL, 679 NULL, 0, cdp->debugvar, 0, 680 CTL_DEBUG, i, CTL_DEBUG_VALUE, CTL_EOL); 681 sysctl_createv(clog, 0, NULL, NULL, 682 CTLFLAG_PERMANENT, 683 CTLTYPE_INT, cdp->debugname, NULL, 684 NULL, 0, cdp->debugvar, 0, 685 CTL_DEBUG, CTL_CREATE, CTL_EOL); 686 } 687} 688#endif /* DEBUG */ 689 690/* 691 * ******************************************************************** 692 * section 2: private node-specific helper routines. 693 * ******************************************************************** 694 */ 695 696/* 697 * sysctl helper routine for kern.maxvnodes. Drain vnodes if 698 * new value is lower than desiredvnodes and then calls reinit 699 * routines that needs to adjust to the new value. 700 */ 701static int 702sysctl_kern_maxvnodes(SYSCTLFN_ARGS) 703{ 704 int error, new_vnodes, old_vnodes, new_max; 705 struct sysctlnode node; 706 707 new_vnodes = desiredvnodes; 708 node = *rnode; 709 node.sysctl_data = &new_vnodes; 710 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 711 if (error || newp == NULL) 712 return (error); 713 714 /* 715 * sysctl passes down unsigned values, require them 716 * to be positive 717 */ 718 if (new_vnodes <= 0) 719 return (EINVAL); 720 721 /* Limits: 75% of kmem and physical memory. */ 722 new_max = calc_cache_size(vmem_size(kmem_arena, VMEM_FREE|VMEM_ALLOC), 723 75, 75) / VNODE_COST; 724 if (new_vnodes > new_max) 725 new_vnodes = new_max; 726 727 old_vnodes = desiredvnodes; 728 desiredvnodes = new_vnodes; 729 error = vfs_drainvnodes(); 730 if (error) { 731 desiredvnodes = old_vnodes; 732 return (error); 733 } 734 vfs_reinit(); 735 nchreinit(); 736 737 return (0); 738} 739 740/* 741 * sysctl helper routine for kern.messages. 742 * Alters boothowto to display kernel messages in increasing verbosity 743 * from 0 to 4. 744 */ 745 746#define MAXMESSAGES 4 747static int 748sysctl_kern_messages(SYSCTLFN_ARGS) 749{ 750 int error, messageverbose, messagemask, newboothowto; 751 struct sysctlnode node; 752 753 messagemask = (AB_NORMAL|AB_QUIET|AB_SILENT|AB_VERBOSE|AB_DEBUG); 754 switch (boothowto & messagemask) { 755 case AB_SILENT: 756 messageverbose = 0; 757 break; 758 case AB_QUIET: 759 messageverbose = 1; 760 break; 761 case AB_VERBOSE: 762 messageverbose = 3; 763 break; 764 case AB_DEBUG: 765 messageverbose = 4; 766 break; 767 case AB_NORMAL: 768 default: 769 messageverbose = 2; 770 } 771 772 node = *rnode; 773 node.sysctl_data = &messageverbose; 774 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 775 if (error || newp == NULL) 776 return (error); 777 if (messageverbose < 0 || messageverbose > MAXMESSAGES) 778 return EINVAL; 779 780 /* Set boothowto */ 781 newboothowto = boothowto & ~messagemask; 782 783 switch (messageverbose) { 784 case 0: 785 newboothowto |= AB_SILENT; 786 break; 787 case 1: 788 newboothowto |= AB_QUIET; 789 break; 790 case 3: 791 newboothowto |= AB_VERBOSE; 792 break; 793 case 4: 794 newboothowto |= AB_DEBUG; 795 break; 796 case 2: 797 default: /* Messages default to normal. */ 798 break; 799 } 800 801 boothowto = newboothowto; 802 803 return (0); 804} 805 806/* 807 * sysctl helper routine for the kern.boottime node 808 */ 809static int 810sysctl_kern_boottime(SYSCTLFN_ARGS) 811{ 812 struct sysctlnode node; 813 struct timespec ts; 814 815 getnanoboottime(&ts); 816 node = *rnode; 817 node.sysctl_data = &ts; 818 return (sysctl_lookup(SYSCTLFN_CALL(&node))); 819} 820 821/* 822 * sysctl helper routine for rtc_offset - set time after changes 823 */ 824static int 825sysctl_kern_rtc_offset(SYSCTLFN_ARGS) 826{ 827 struct timespec ts, delta; 828 int error, new_rtc_offset; 829 struct sysctlnode node; 830 831 new_rtc_offset = rtc_offset; 832 node = *rnode; 833 node.sysctl_data = &new_rtc_offset; 834 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 835 if (error || newp == NULL) 836 return (error); 837 838 if (kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_TIME, 839 KAUTH_REQ_SYSTEM_TIME_RTCOFFSET, 840 KAUTH_ARG(new_rtc_offset), NULL, NULL)) 841 return (EPERM); 842 if (rtc_offset == new_rtc_offset) 843 return (0); 844 845 /* if we change the offset, adjust the time */ 846 nanotime(&ts); 847 delta.tv_sec = 60 * (new_rtc_offset - rtc_offset); 848 delta.tv_nsec = 0; 849 timespecadd(&ts, &delta, &ts); 850 rtc_offset = new_rtc_offset; 851 return (settime(l->l_proc, &ts)); 852} 853 854/* 855 * sysctl helper routine for kern.maxproc. Ensures that the new 856 * values are not too low or too high. 857 */ 858static int 859sysctl_kern_maxproc(SYSCTLFN_ARGS) 860{ 861 int error, nmaxproc; 862 struct sysctlnode node; 863 864 nmaxproc = maxproc; 865 node = *rnode; 866 node.sysctl_data = &nmaxproc; 867 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 868 if (error || newp == NULL) 869 return (error); 870 871 if (nmaxproc < 0 || nmaxproc >= PID_MAX) 872 return (EINVAL); 873#ifdef __HAVE_CPU_MAXPROC 874 if (nmaxproc > cpu_maxproc()) 875 return (EINVAL); 876#endif 877 error = 0; 878#ifdef __HAVE_MAXPROC_HOOK 879 error = cpu_maxproc_hook(nmaxproc); 880#endif 881 if (error) 882 return error; 883 884 maxproc = nmaxproc; 885 886 return (0); 887} 888 889/* 890 * sysctl helper function for kern.hostid. The hostid is a long, but 891 * we export it as an int, so we need to give it a little help. 892 */ 893static int 894sysctl_kern_hostid(SYSCTLFN_ARGS) 895{ 896 int error, inthostid; 897 struct sysctlnode node; 898 899 inthostid = hostid; /* XXX assumes sizeof int <= sizeof long */ 900 node = *rnode; 901 node.sysctl_data = &inthostid; 902 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 903 if (error || newp == NULL) 904 return (error); 905 906 hostid = (unsigned)inthostid; 907 908 return (0); 909} 910 911/* 912 * sysctl helper routine for kern.defcorename. In the case of a new 913 * string being assigned, check that it's not a zero-length string. 914 * (XXX the check in -current doesn't work, but do we really care?) 915 */ 916static int 917sysctl_kern_defcorename(SYSCTLFN_ARGS) 918{ 919 int error; 920 char *newcorename; 921 struct sysctlnode node; 922 923 newcorename = PNBUF_GET(); 924 node = *rnode; 925 node.sysctl_data = &newcorename[0]; 926 memcpy(node.sysctl_data, rnode->sysctl_data, MAXPATHLEN); 927 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 928 if (error || newp == NULL) { 929 goto done; 930 } 931 932 /* 933 * when sysctl_lookup() deals with a string, it's guaranteed 934 * to come back nul terminated. So there. :) 935 */ 936 if (strlen(newcorename) == 0) { 937 error = EINVAL; 938 } else { 939 memcpy(rnode->sysctl_data, node.sysctl_data, MAXPATHLEN); 940 error = 0; 941 } 942done: 943 PNBUF_PUT(newcorename); 944 return error; 945} 946 947/* 948 * sysctl helper routine for kern.cp_time node. Adds up cpu time 949 * across all cpus. 950 */ 951static int 952sysctl_kern_cptime(SYSCTLFN_ARGS) 953{ 954 struct sysctlnode node = *rnode; 955 uint64_t *cp_time = NULL; 956 int error, n = ncpu, i; 957 struct cpu_info *ci; 958 CPU_INFO_ITERATOR cii; 959 960 /* 961 * if you specifically pass a buffer that is the size of the 962 * sum, or if you are probing for the size, you get the "sum" 963 * of cp_time (and the size thereof) across all processors. 964 * 965 * alternately, you can pass an additional mib number and get 966 * cp_time for that particular processor. 967 */ 968 switch (namelen) { 969 case 0: 970 if (*oldlenp == sizeof(uint64_t) * CPUSTATES || oldp == NULL) { 971 node.sysctl_size = sizeof(uint64_t) * CPUSTATES; 972 n = -1; /* SUM */ 973 } 974 else { 975 node.sysctl_size = n * sizeof(uint64_t) * CPUSTATES; 976 n = -2; /* ALL */ 977 } 978 break; 979 case 1: 980 if (name[0] < 0 || name[0] >= n) 981 return (ENOENT); /* ENOSUCHPROCESSOR */ 982 node.sysctl_size = sizeof(uint64_t) * CPUSTATES; 983 n = name[0]; 984 /* 985 * adjust these so that sysctl_lookup() will be happy 986 */ 987 name++; 988 namelen--; 989 break; 990 default: 991 return (EINVAL); 992 } 993 994 cp_time = kmem_alloc(node.sysctl_size, KM_SLEEP); 995 node.sysctl_data = cp_time; 996 memset(cp_time, 0, node.sysctl_size); 997 998 for (CPU_INFO_FOREACH(cii, ci)) { 999 if (n <= 0) { 1000 for (i = 0; i < CPUSTATES; i++) { 1001 cp_time[i] += ci->ci_schedstate.spc_cp_time[i]; 1002 } 1003 } 1004 /* 1005 * if a specific processor was requested and we just 1006 * did it, we're done here 1007 */ 1008 if (n == 0) 1009 break; 1010 /* 1011 * if doing "all", skip to next cp_time set for next processor 1012 */ 1013 if (n == -2) 1014 cp_time += CPUSTATES; 1015 /* 1016 * if we're doing a specific processor, we're one 1017 * processor closer 1018 */ 1019 if (n > 0) 1020 n--; 1021 } 1022 1023 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 1024 kmem_free(node.sysctl_data, node.sysctl_size); 1025 return (error); 1026} 1027 1028#if NPTY > 0 1029/* 1030 * sysctl helper routine for kern.maxptys. Ensures that any new value 1031 * is acceptable to the pty subsystem. 1032 */ 1033static int 1034sysctl_kern_maxptys(SYSCTLFN_ARGS) 1035{ 1036 int pty_maxptys(int, int); /* defined in kern/tty_pty.c */ 1037 int error, xmax; 1038 struct sysctlnode node; 1039 1040 /* get current value of maxptys */ 1041 xmax = pty_maxptys(0, 0); 1042 1043 node = *rnode; 1044 node.sysctl_data = &xmax; 1045 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 1046 if (error || newp == NULL) 1047 return (error); 1048 1049 if (xmax != pty_maxptys(xmax, 1)) 1050 return (EINVAL); 1051 1052 return (0); 1053} 1054#endif /* NPTY > 0 */ 1055 1056/* 1057 * sysctl helper routine to do kern.lwp.* work. 1058 */ 1059static int 1060sysctl_kern_lwp(SYSCTLFN_ARGS) 1061{ 1062 struct kinfo_lwp klwp; 1063 struct proc *p; 1064 struct lwp *l2, *l3; 1065 char *where, *dp; 1066 int pid, elem_size, elem_count; 1067 int buflen, needed, error; 1068 bool gotit; 1069 1070 if (namelen == 1 && name[0] == CTL_QUERY) 1071 return (sysctl_query(SYSCTLFN_CALL(rnode))); 1072 1073 dp = where = oldp; 1074 buflen = where != NULL ? *oldlenp : 0; 1075 error = needed = 0; 1076 1077 if (newp != NULL || namelen != 3) 1078 return (EINVAL); 1079 pid = name[0]; 1080 elem_size = name[1]; 1081 elem_count = name[2]; 1082 1083 sysctl_unlock(); 1084 if (pid == -1) { 1085 mutex_enter(proc_lock); 1086 PROCLIST_FOREACH(p, &allproc) { 1087 /* Grab a hold on the process. */ 1088 if (!rw_tryenter(&p->p_reflock, RW_READER)) { 1089 continue; 1090 } 1091 mutex_exit(proc_lock); 1092 1093 mutex_enter(p->p_lock); 1094 LIST_FOREACH(l2, &p->p_lwps, l_sibling) { 1095 if (buflen >= elem_size && elem_count > 0) { 1096 lwp_lock(l2); 1097 fill_lwp(l2, &klwp); 1098 lwp_unlock(l2); 1099 mutex_exit(p->p_lock); 1100 1101 /* 1102 * Copy out elem_size, but not 1103 * larger than the size of a 1104 * struct kinfo_proc2. 1105 */ 1106 error = dcopyout(l, &klwp, dp, 1107 uimin(sizeof(klwp), elem_size)); 1108 if (error) { 1109 rw_exit(&p->p_reflock); 1110 goto cleanup; 1111 } 1112 mutex_enter(p->p_lock); 1113 LIST_FOREACH(l3, &p->p_lwps, 1114 l_sibling) { 1115 if (l2 == l3) 1116 break; 1117 } 1118 if (l3 == NULL) { 1119 mutex_exit(p->p_lock); 1120 rw_exit(&p->p_reflock); 1121 error = EAGAIN; 1122 goto cleanup; 1123 } 1124 dp += elem_size; 1125 buflen -= elem_size; 1126 elem_count--; 1127 } 1128 needed += elem_size; 1129 } 1130 mutex_exit(p->p_lock); 1131 1132 /* Drop reference to process. */ 1133 mutex_enter(proc_lock); 1134 rw_exit(&p->p_reflock); 1135 } 1136 mutex_exit(proc_lock); 1137 } else { 1138 mutex_enter(proc_lock); 1139 p = proc_find(pid); 1140 if (p == NULL) { 1141 error = ESRCH; 1142 mutex_exit(proc_lock); 1143 goto cleanup; 1144 } 1145 /* Grab a hold on the process. */ 1146 gotit = rw_tryenter(&p->p_reflock, RW_READER); 1147 mutex_exit(proc_lock); 1148 if (!gotit) { 1149 error = ESRCH; 1150 goto cleanup; 1151 } 1152 1153 mutex_enter(p->p_lock); 1154 LIST_FOREACH(l2, &p->p_lwps, l_sibling) { 1155 if (buflen >= elem_size && elem_count > 0) { 1156 lwp_lock(l2); 1157 fill_lwp(l2, &klwp); 1158 lwp_unlock(l2); 1159 mutex_exit(p->p_lock); 1160 /* 1161 * Copy out elem_size, but not larger than 1162 * the size of a struct kinfo_proc2. 1163 */ 1164 error = dcopyout(l, &klwp, dp, 1165 uimin(sizeof(klwp), elem_size)); 1166 if (error) { 1167 rw_exit(&p->p_reflock); 1168 goto cleanup; 1169 } 1170 mutex_enter(p->p_lock); 1171 LIST_FOREACH(l3, &p->p_lwps, l_sibling) { 1172 if (l2 == l3) 1173 break; 1174 } 1175 if (l3 == NULL) { 1176 mutex_exit(p->p_lock); 1177 rw_exit(&p->p_reflock); 1178 error = EAGAIN; 1179 goto cleanup; 1180 } 1181 dp += elem_size; 1182 buflen -= elem_size; 1183 elem_count--; 1184 } 1185 needed += elem_size; 1186 } 1187 mutex_exit(p->p_lock); 1188 1189 /* Drop reference to process. */ 1190 rw_exit(&p->p_reflock); 1191 } 1192 1193 if (where != NULL) { 1194 *oldlenp = dp - where; 1195 if (needed > *oldlenp) { 1196 sysctl_relock(); 1197 return (ENOMEM); 1198 } 1199 } else { 1200 needed += KERN_LWPSLOP; 1201 *oldlenp = needed; 1202 } 1203 error = 0; 1204 cleanup: 1205 sysctl_relock(); 1206 return (error); 1207} 1208 1209/* 1210 * sysctl helper routine for kern.forkfsleep node. Ensures that the 1211 * given value is not too large or two small, and is at least one 1212 * timer tick if not zero. 1213 */ 1214static int 1215sysctl_kern_forkfsleep(SYSCTLFN_ARGS) 1216{ 1217 /* userland sees value in ms, internally is in ticks */ 1218 extern int forkfsleep; /* defined in kern/kern_fork.c */ 1219 int error, timo, lsleep; 1220 struct sysctlnode node; 1221 1222 lsleep = forkfsleep * 1000 / hz; 1223 node = *rnode; 1224 node.sysctl_data = &lsleep; 1225 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 1226 if (error || newp == NULL) 1227 return (error); 1228 1229 /* refuse negative values, and overly 'long time' */ 1230 if (lsleep < 0 || lsleep > MAXSLP * 1000) 1231 return (EINVAL); 1232 1233 timo = mstohz(lsleep); 1234 1235 /* if the interval is >0 ms && <1 tick, use 1 tick */ 1236 if (lsleep != 0 && timo == 0) 1237 forkfsleep = 1; 1238 else 1239 forkfsleep = timo; 1240 1241 return (0); 1242} 1243 1244/* 1245 * sysctl helper routine for kern.root_partition 1246 */ 1247static int 1248sysctl_kern_root_partition(SYSCTLFN_ARGS) 1249{ 1250 int rootpart = DISKPART(rootdev); 1251 struct sysctlnode node = *rnode; 1252 1253 node.sysctl_data = &rootpart; 1254 return (sysctl_lookup(SYSCTLFN_CALL(&node))); 1255} 1256 1257/* 1258 * sysctl helper function for kern.drivers 1259 */ 1260static int 1261sysctl_kern_drivers(SYSCTLFN_ARGS) 1262{ 1263 int error; 1264 size_t buflen; 1265 struct kinfo_drivers kd; 1266 char *start, *where; 1267 const char *dname; 1268 int i; 1269 extern struct devsw_conv *devsw_conv; 1270 extern int max_devsw_convs; 1271 1272 start = where = oldp; 1273 buflen = *oldlenp; 1274 if (where == NULL) { 1275 *oldlenp = max_devsw_convs * sizeof kd; 1276 return 0; 1277 } 1278 1279 /* 1280 * An array of kinfo_drivers structures 1281 */ 1282 error = 0; 1283 sysctl_unlock(); 1284 mutex_enter(&device_lock); 1285 for (i = 0; i < max_devsw_convs; i++) { 1286 dname = devsw_conv[i].d_name; 1287 if (dname == NULL) 1288 continue; 1289 if (buflen < sizeof kd) { 1290 error = ENOMEM; 1291 break; 1292 } 1293 memset(&kd, 0, sizeof(kd)); 1294 kd.d_bmajor = devsw_conv[i].d_bmajor; 1295 kd.d_cmajor = devsw_conv[i].d_cmajor; 1296 strlcpy(kd.d_name, dname, sizeof kd.d_name); 1297 mutex_exit(&device_lock); 1298 error = dcopyout(l, &kd, where, sizeof kd); 1299 mutex_enter(&device_lock); 1300 if (error != 0) 1301 break; 1302 buflen -= sizeof kd; 1303 where += sizeof kd; 1304 } 1305 mutex_exit(&device_lock); 1306 sysctl_relock(); 1307 *oldlenp = where - start; 1308 return error; 1309} 1310 1311static int 1312sysctl_security_setidcore(SYSCTLFN_ARGS) 1313{ 1314 int newsize, error; 1315 struct sysctlnode node; 1316 1317 node = *rnode; 1318 node.sysctl_data = &newsize; 1319 newsize = *(int *)rnode->sysctl_data; 1320 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 1321 if (error || newp == NULL) 1322 return error; 1323 1324 if (kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_SETIDCORE, 1325 0, NULL, NULL, NULL)) 1326 return (EPERM); 1327 1328 *(int *)rnode->sysctl_data = newsize; 1329 1330 return 0; 1331} 1332 1333static int 1334sysctl_security_setidcorename(SYSCTLFN_ARGS) 1335{ 1336 int error; 1337 char *newsetidcorename; 1338 struct sysctlnode node; 1339 1340 newsetidcorename = PNBUF_GET(); 1341 node = *rnode; 1342 node.sysctl_data = newsetidcorename; 1343 memcpy(node.sysctl_data, rnode->sysctl_data, MAXPATHLEN); 1344 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 1345 if (error || newp == NULL) { 1346 goto out; 1347 } 1348 if (kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_SETIDCORE, 1349 0, NULL, NULL, NULL)) { 1350 error = EPERM; 1351 goto out; 1352 } 1353 if (strlen(newsetidcorename) == 0) { 1354 error = EINVAL; 1355 goto out; 1356 } 1357 memcpy(rnode->sysctl_data, node.sysctl_data, MAXPATHLEN); 1358out: 1359 PNBUF_PUT(newsetidcorename); 1360 return error; 1361} 1362 1363/* 1364 * sysctl helper routine for kern.cp_id node. Maps cpus to their 1365 * cpuids. 1366 */ 1367static int 1368sysctl_kern_cpid(SYSCTLFN_ARGS) 1369{ 1370 struct sysctlnode node = *rnode; 1371 uint64_t *cp_id = NULL; 1372 int error, n = ncpu; 1373 struct cpu_info *ci; 1374 CPU_INFO_ITERATOR cii; 1375 1376 /* 1377 * Here you may either retrieve a single cpu id or the whole 1378 * set. The size you get back when probing depends on what 1379 * you ask for. 1380 */ 1381 switch (namelen) { 1382 case 0: 1383 node.sysctl_size = n * sizeof(uint64_t); 1384 n = -2; /* ALL */ 1385 break; 1386 case 1: 1387 if (name[0] < 0 || name[0] >= n) 1388 return (ENOENT); /* ENOSUCHPROCESSOR */ 1389 node.sysctl_size = sizeof(uint64_t); 1390 n = name[0]; 1391 /* 1392 * adjust these so that sysctl_lookup() will be happy 1393 */ 1394 name++; 1395 namelen--; 1396 break; 1397 default: 1398 return (EINVAL); 1399 } 1400 1401 cp_id = kmem_alloc(node.sysctl_size, KM_SLEEP); 1402 node.sysctl_data = cp_id; 1403 memset(cp_id, 0, node.sysctl_size); 1404 1405 for (CPU_INFO_FOREACH(cii, ci)) { 1406 if (n <= 0) 1407 cp_id[0] = cpu_index(ci); 1408 /* 1409 * if a specific processor was requested and we just 1410 * did it, we're done here 1411 */ 1412 if (n == 0) 1413 break; 1414 /* 1415 * if doing "all", skip to next cp_id slot for next processor 1416 */ 1417 if (n == -2) 1418 cp_id++; 1419 /* 1420 * if we're doing a specific processor, we're one 1421 * processor closer 1422 */ 1423 if (n > 0) 1424 n--; 1425 } 1426 1427 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 1428 kmem_free(node.sysctl_data, node.sysctl_size); 1429 return (error); 1430} 1431 1432/* 1433 * sysctl helper routine for hw.usermem and hw.usermem64. Values are 1434 * calculate on the fly taking into account integer overflow and the 1435 * current wired count. 1436 */ 1437static int 1438sysctl_hw_usermem(SYSCTLFN_ARGS) 1439{ 1440 u_int ui; 1441 u_quad_t uq; 1442 struct sysctlnode node; 1443 1444 node = *rnode; 1445 switch (rnode->sysctl_num) { 1446 case HW_USERMEM: 1447 if ((ui = physmem - uvmexp.wired) > (UINT_MAX / PAGE_SIZE)) 1448 ui = UINT_MAX; 1449 else 1450 ui *= PAGE_SIZE; 1451 node.sysctl_data = &ui; 1452 break; 1453 case HW_USERMEM64: 1454 uq = (u_quad_t)(physmem - uvmexp.wired) * PAGE_SIZE; 1455 node.sysctl_data = &uq; 1456 break; 1457 default: 1458 return (EINVAL); 1459 } 1460 1461 return (sysctl_lookup(SYSCTLFN_CALL(&node))); 1462} 1463 1464/* 1465 * sysctl helper routine for kern.cnmagic node. Pulls the old value 1466 * out, encoded, and stuffs the new value in for decoding. 1467 */ 1468static int 1469sysctl_hw_cnmagic(SYSCTLFN_ARGS) 1470{ 1471 char magic[CNS_LEN]; 1472 int error; 1473 struct sysctlnode node; 1474 1475 if (oldp) 1476 cn_get_magic(magic, CNS_LEN); 1477 node = *rnode; 1478 node.sysctl_data = &magic[0]; 1479 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 1480 if (error || newp == NULL) 1481 return (error); 1482 1483 return (cn_set_magic(magic)); 1484} 1485 1486/* 1487 * ******************************************************************** 1488 * section 3: public helper routines that are used for more than one 1489 * node 1490 * ******************************************************************** 1491 */ 1492 1493/* 1494 * sysctl helper routine for the kern.root_device node and some ports' 1495 * machdep.root_device nodes. 1496 */ 1497int 1498sysctl_root_device(SYSCTLFN_ARGS) 1499{ 1500 struct sysctlnode node; 1501 1502 node = *rnode; 1503 node.sysctl_data = __UNCONST(device_xname(root_device)); 1504 node.sysctl_size = strlen(device_xname(root_device)) + 1; 1505 return (sysctl_lookup(SYSCTLFN_CALL(&node))); 1506} 1507 1508/* 1509 * sysctl helper routine for kern.consdev, dependent on the current 1510 * state of the console. Also used for machdep.console_device on some 1511 * ports. 1512 */ 1513int 1514sysctl_consdev(SYSCTLFN_ARGS) 1515{ 1516 dev_t consdev; 1517 uint32_t oconsdev; 1518 struct sysctlnode node; 1519 1520 if (cn_tab != NULL) 1521 consdev = cn_tab->cn_dev; 1522 else 1523 consdev = NODEV; 1524 node = *rnode; 1525 switch (*oldlenp) { 1526 case sizeof(consdev): 1527 node.sysctl_data = &consdev; 1528 node.sysctl_size = sizeof(consdev); 1529 break; 1530 case sizeof(oconsdev): 1531 oconsdev = (uint32_t)consdev; 1532 node.sysctl_data = &oconsdev; 1533 node.sysctl_size = sizeof(oconsdev); 1534 break; 1535 default: 1536 return EINVAL; 1537 } 1538 return (sysctl_lookup(SYSCTLFN_CALL(&node))); 1539} 1540 1541/* 1542 * ******************************************************************** 1543 * section 4: support for some helpers 1544 * ******************************************************************** 1545 */ 1546 1547 1548/* 1549 * Fill in a kinfo_lwp structure for the specified lwp. 1550 */ 1551static void 1552fill_lwp(struct lwp *l, struct kinfo_lwp *kl) 1553{ 1554 const bool allowaddr = get_expose_address(curproc); 1555 struct proc *p = l->l_proc; 1556 struct timeval tv; 1557 1558 KASSERT(lwp_locked(l, NULL)); 1559 1560 memset(kl, 0, sizeof(*kl)); 1561 1562 kl->l_forw = 0; 1563 kl->l_back = 0; 1564 COND_SET_VALUE(kl->l_laddr, PTRTOUINT64(l), allowaddr); 1565 COND_SET_VALUE(kl->l_addr, PTRTOUINT64(l->l_addr), allowaddr); 1566 kl->l_stat = l->l_stat; 1567 kl->l_lid = l->l_lid; 1568 kl->l_flag = L_INMEM; 1569 kl->l_flag |= sysctl_map_flags(sysctl_lwpprflagmap, l->l_prflag); 1570 kl->l_flag |= sysctl_map_flags(sysctl_lwpflagmap, l->l_flag); 1571 1572 kl->l_swtime = l->l_swtime; 1573 kl->l_slptime = l->l_slptime; 1574 if (l->l_stat == LSONPROC) 1575 kl->l_schedflags = l->l_cpu->ci_schedstate.spc_flags; 1576 else 1577 kl->l_schedflags = 0; 1578 kl->l_priority = lwp_eprio(l); 1579 kl->l_usrpri = l->l_priority; 1580 if (l->l_wchan) 1581 strncpy(kl->l_wmesg, l->l_wmesg, sizeof(kl->l_wmesg)); 1582 COND_SET_VALUE(kl->l_wchan, PTRTOUINT64(l->l_wchan), allowaddr); 1583 kl->l_cpuid = cpu_index(l->l_cpu); 1584 bintime2timeval(&l->l_rtime, &tv); 1585 kl->l_rtime_sec = tv.tv_sec; 1586 kl->l_rtime_usec = tv.tv_usec; 1587 kl->l_cpticks = l->l_cpticks; 1588 kl->l_pctcpu = l->l_pctcpu; 1589 kl->l_pid = p->p_pid; 1590 if (l->l_name == NULL) 1591 kl->l_name[0] = '\0'; 1592 else 1593 strlcpy(kl->l_name, l->l_name, sizeof(kl->l_name)); 1594} 1595