1 /* $NetBSD: init_sysctl.c,v 1.226 2020/05/23 23:42:43 ad 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.226 2020/05/23 23:42:43 ad 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 72 int security_setidcore_dump; 73 char security_setidcore_path[MAXPATHLEN] = "/var/crash/%n.core"; 74 uid_t security_setidcore_owner = 0; 75 gid_t security_setidcore_group = 0; 76 mode_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 84 int kern_has_sysvmsg = 0; 85 int kern_has_sysvshm = 0; 86 int kern_has_sysvsem = 0; 87 88 static 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 98 static int dcopyout(struct lwp *, const void *, void *, size_t); 99 100 static int 101 dcopyout(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 111 static int sysctl_kern_maxvnodes(SYSCTLFN_PROTO); 112 static int sysctl_kern_messages(SYSCTLFN_PROTO); 113 static int sysctl_kern_boottime(SYSCTLFN_PROTO); 114 static int sysctl_kern_rtc_offset(SYSCTLFN_PROTO); 115 static int sysctl_kern_maxproc(SYSCTLFN_PROTO); 116 static int sysctl_kern_hostid(SYSCTLFN_PROTO); 117 static int sysctl_kern_defcorename(SYSCTLFN_PROTO); 118 static int sysctl_kern_cptime(SYSCTLFN_PROTO); 119 #if NPTY > 0 120 static int sysctl_kern_maxptys(SYSCTLFN_PROTO); 121 #endif /* NPTY > 0 */ 122 static int sysctl_kern_lwp(SYSCTLFN_PROTO); 123 static int sysctl_kern_forkfsleep(SYSCTLFN_PROTO); 124 static int sysctl_kern_root_partition(SYSCTLFN_PROTO); 125 static int sysctl_kern_drivers(SYSCTLFN_PROTO); 126 static int sysctl_security_setidcore(SYSCTLFN_PROTO); 127 static int sysctl_security_setidcorename(SYSCTLFN_PROTO); 128 static int sysctl_kern_cpid(SYSCTLFN_PROTO); 129 static int sysctl_hw_usermem(SYSCTLFN_PROTO); 130 static int sysctl_hw_cnmagic(SYSCTLFN_PROTO); 131 132 static 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 */ 146 SYSCTL_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 594 SYSCTL_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 */ 621 struct ctldebug /* debug0, */ /* debug1, */ debug2, debug3, debug4; 622 struct ctldebug debug5, debug6, debug7, debug8, debug9; 623 struct ctldebug debug10, debug11, debug12, debug13, debug14; 624 struct ctldebug debug15, debug16, debug17, debug18, debug19; 625 static 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 */ 637 SYSCTL_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 */ 701 static int 702 sysctl_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 736 return (0); 737 } 738 739 /* 740 * sysctl helper routine for kern.messages. 741 * Alters boothowto to display kernel messages in increasing verbosity 742 * from 0 to 4. 743 */ 744 745 #define MAXMESSAGES 4 746 static int 747 sysctl_kern_messages(SYSCTLFN_ARGS) 748 { 749 int error, messageverbose, messagemask, newboothowto; 750 struct sysctlnode node; 751 752 messagemask = (AB_NORMAL|AB_QUIET|AB_SILENT|AB_VERBOSE|AB_DEBUG); 753 switch (boothowto & messagemask) { 754 case AB_SILENT: 755 messageverbose = 0; 756 break; 757 case AB_QUIET: 758 messageverbose = 1; 759 break; 760 case AB_VERBOSE: 761 messageverbose = 3; 762 break; 763 case AB_DEBUG: 764 messageverbose = 4; 765 break; 766 case AB_NORMAL: 767 default: 768 messageverbose = 2; 769 } 770 771 node = *rnode; 772 node.sysctl_data = &messageverbose; 773 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 774 if (error || newp == NULL) 775 return (error); 776 if (messageverbose < 0 || messageverbose > MAXMESSAGES) 777 return EINVAL; 778 779 /* Set boothowto */ 780 newboothowto = boothowto & ~messagemask; 781 782 switch (messageverbose) { 783 case 0: 784 newboothowto |= AB_SILENT; 785 break; 786 case 1: 787 newboothowto |= AB_QUIET; 788 break; 789 case 3: 790 newboothowto |= AB_VERBOSE; 791 break; 792 case 4: 793 newboothowto |= AB_DEBUG; 794 break; 795 case 2: 796 default: /* Messages default to normal. */ 797 break; 798 } 799 800 boothowto = newboothowto; 801 802 return (0); 803 } 804 805 /* 806 * sysctl helper routine for the kern.boottime node 807 */ 808 static int 809 sysctl_kern_boottime(SYSCTLFN_ARGS) 810 { 811 struct sysctlnode node; 812 struct timespec ts; 813 814 getnanoboottime(&ts); 815 node = *rnode; 816 node.sysctl_data = &ts; 817 return (sysctl_lookup(SYSCTLFN_CALL(&node))); 818 } 819 820 /* 821 * sysctl helper routine for rtc_offset - set time after changes 822 */ 823 static int 824 sysctl_kern_rtc_offset(SYSCTLFN_ARGS) 825 { 826 struct timespec ts, delta; 827 int error, new_rtc_offset; 828 struct sysctlnode node; 829 830 new_rtc_offset = rtc_offset; 831 node = *rnode; 832 node.sysctl_data = &new_rtc_offset; 833 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 834 if (error || newp == NULL) 835 return (error); 836 837 if (kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_TIME, 838 KAUTH_REQ_SYSTEM_TIME_RTCOFFSET, 839 KAUTH_ARG(new_rtc_offset), NULL, NULL)) 840 return (EPERM); 841 if (rtc_offset == new_rtc_offset) 842 return (0); 843 844 /* if we change the offset, adjust the time */ 845 nanotime(&ts); 846 delta.tv_sec = 60 * (new_rtc_offset - rtc_offset); 847 delta.tv_nsec = 0; 848 timespecadd(&ts, &delta, &ts); 849 rtc_offset = new_rtc_offset; 850 return (settime(l->l_proc, &ts)); 851 } 852 853 /* 854 * sysctl helper routine for kern.maxproc. Ensures that the new 855 * values are not too low or too high. 856 */ 857 static int 858 sysctl_kern_maxproc(SYSCTLFN_ARGS) 859 { 860 int error, nmaxproc; 861 struct sysctlnode node; 862 863 nmaxproc = maxproc; 864 node = *rnode; 865 node.sysctl_data = &nmaxproc; 866 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 867 if (error || newp == NULL) 868 return (error); 869 870 if (nmaxproc < 0 || nmaxproc >= PID_MAX) 871 return (EINVAL); 872 #ifdef __HAVE_CPU_MAXPROC 873 if (nmaxproc > cpu_maxproc()) 874 return (EINVAL); 875 #endif 876 error = 0; 877 #ifdef __HAVE_MAXPROC_HOOK 878 error = cpu_maxproc_hook(nmaxproc); 879 #endif 880 if (error) 881 return error; 882 883 maxproc = nmaxproc; 884 885 return (0); 886 } 887 888 /* 889 * sysctl helper function for kern.hostid. The hostid is a long, but 890 * we export it as an int, so we need to give it a little help. 891 */ 892 static int 893 sysctl_kern_hostid(SYSCTLFN_ARGS) 894 { 895 int error, inthostid; 896 struct sysctlnode node; 897 898 inthostid = hostid; /* XXX assumes sizeof int <= sizeof long */ 899 node = *rnode; 900 node.sysctl_data = &inthostid; 901 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 902 if (error || newp == NULL) 903 return (error); 904 905 hostid = (unsigned)inthostid; 906 907 return (0); 908 } 909 910 /* 911 * sysctl helper routine for kern.defcorename. In the case of a new 912 * string being assigned, check that it's not a zero-length string. 913 * (XXX the check in -current doesn't work, but do we really care?) 914 */ 915 static int 916 sysctl_kern_defcorename(SYSCTLFN_ARGS) 917 { 918 int error; 919 char *newcorename; 920 struct sysctlnode node; 921 922 newcorename = PNBUF_GET(); 923 node = *rnode; 924 node.sysctl_data = &newcorename[0]; 925 memcpy(node.sysctl_data, rnode->sysctl_data, MAXPATHLEN); 926 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 927 if (error || newp == NULL) { 928 goto done; 929 } 930 931 /* 932 * when sysctl_lookup() deals with a string, it's guaranteed 933 * to come back nul terminated. So there. :) 934 */ 935 if (strlen(newcorename) == 0) { 936 error = EINVAL; 937 } else { 938 memcpy(rnode->sysctl_data, node.sysctl_data, MAXPATHLEN); 939 error = 0; 940 } 941 done: 942 PNBUF_PUT(newcorename); 943 return error; 944 } 945 946 /* 947 * sysctl helper routine for kern.cp_time node. Adds up cpu time 948 * across all cpus. 949 */ 950 static int 951 sysctl_kern_cptime(SYSCTLFN_ARGS) 952 { 953 struct sysctlnode node = *rnode; 954 uint64_t *cp_time = NULL; 955 int error, n = ncpu, i; 956 struct cpu_info *ci; 957 CPU_INFO_ITERATOR cii; 958 959 /* 960 * if you specifically pass a buffer that is the size of the 961 * sum, or if you are probing for the size, you get the "sum" 962 * of cp_time (and the size thereof) across all processors. 963 * 964 * alternately, you can pass an additional mib number and get 965 * cp_time for that particular processor. 966 */ 967 switch (namelen) { 968 case 0: 969 if (*oldlenp == sizeof(uint64_t) * CPUSTATES || oldp == NULL) { 970 node.sysctl_size = sizeof(uint64_t) * CPUSTATES; 971 n = -1; /* SUM */ 972 } 973 else { 974 node.sysctl_size = n * sizeof(uint64_t) * CPUSTATES; 975 n = -2; /* ALL */ 976 } 977 break; 978 case 1: 979 if (name[0] < 0 || name[0] >= n) 980 return (ENOENT); /* ENOSUCHPROCESSOR */ 981 node.sysctl_size = sizeof(uint64_t) * CPUSTATES; 982 n = name[0]; 983 /* 984 * adjust these so that sysctl_lookup() will be happy 985 */ 986 name++; 987 namelen--; 988 break; 989 default: 990 return (EINVAL); 991 } 992 993 cp_time = kmem_alloc(node.sysctl_size, KM_SLEEP); 994 node.sysctl_data = cp_time; 995 memset(cp_time, 0, node.sysctl_size); 996 997 for (CPU_INFO_FOREACH(cii, ci)) { 998 if (n <= 0) { 999 for (i = 0; i < CPUSTATES; i++) { 1000 cp_time[i] += ci->ci_schedstate.spc_cp_time[i]; 1001 } 1002 } 1003 /* 1004 * if a specific processor was requested and we just 1005 * did it, we're done here 1006 */ 1007 if (n == 0) 1008 break; 1009 /* 1010 * if doing "all", skip to next cp_time set for next processor 1011 */ 1012 if (n == -2) 1013 cp_time += CPUSTATES; 1014 /* 1015 * if we're doing a specific processor, we're one 1016 * processor closer 1017 */ 1018 if (n > 0) 1019 n--; 1020 } 1021 1022 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 1023 kmem_free(node.sysctl_data, node.sysctl_size); 1024 return (error); 1025 } 1026 1027 #if NPTY > 0 1028 /* 1029 * sysctl helper routine for kern.maxptys. Ensures that any new value 1030 * is acceptable to the pty subsystem. 1031 */ 1032 static int 1033 sysctl_kern_maxptys(SYSCTLFN_ARGS) 1034 { 1035 int pty_maxptys(int, int); /* defined in kern/tty_pty.c */ 1036 int error, xmax; 1037 struct sysctlnode node; 1038 1039 /* get current value of maxptys */ 1040 xmax = pty_maxptys(0, 0); 1041 1042 node = *rnode; 1043 node.sysctl_data = &xmax; 1044 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 1045 if (error || newp == NULL) 1046 return (error); 1047 1048 if (xmax != pty_maxptys(xmax, 1)) 1049 return (EINVAL); 1050 1051 return (0); 1052 } 1053 #endif /* NPTY > 0 */ 1054 1055 /* 1056 * sysctl helper routine to do kern.lwp.* work. 1057 */ 1058 static int 1059 sysctl_kern_lwp(SYSCTLFN_ARGS) 1060 { 1061 struct kinfo_lwp klwp; 1062 struct proc *p; 1063 struct lwp *l2, *l3; 1064 char *where, *dp; 1065 int pid, elem_size, elem_count; 1066 int buflen, needed, error; 1067 bool gotit; 1068 1069 if (namelen == 1 && name[0] == CTL_QUERY) 1070 return (sysctl_query(SYSCTLFN_CALL(rnode))); 1071 1072 dp = where = oldp; 1073 buflen = where != NULL ? *oldlenp : 0; 1074 error = needed = 0; 1075 1076 if (newp != NULL || namelen != 3) 1077 return (EINVAL); 1078 pid = name[0]; 1079 elem_size = name[1]; 1080 elem_count = name[2]; 1081 1082 sysctl_unlock(); 1083 if (pid == -1) { 1084 mutex_enter(&proc_lock); 1085 PROCLIST_FOREACH(p, &allproc) { 1086 /* Grab a hold on the process. */ 1087 if (!rw_tryenter(&p->p_reflock, RW_READER)) { 1088 continue; 1089 } 1090 mutex_exit(&proc_lock); 1091 1092 mutex_enter(p->p_lock); 1093 LIST_FOREACH(l2, &p->p_lwps, l_sibling) { 1094 if (buflen >= elem_size && elem_count > 0) { 1095 lwp_lock(l2); 1096 fill_lwp(l2, &klwp); 1097 lwp_unlock(l2); 1098 mutex_exit(p->p_lock); 1099 1100 /* 1101 * Copy out elem_size, but not 1102 * larger than the size of a 1103 * struct kinfo_proc2. 1104 */ 1105 error = dcopyout(l, &klwp, dp, 1106 uimin(sizeof(klwp), elem_size)); 1107 if (error) { 1108 rw_exit(&p->p_reflock); 1109 goto cleanup; 1110 } 1111 mutex_enter(p->p_lock); 1112 LIST_FOREACH(l3, &p->p_lwps, 1113 l_sibling) { 1114 if (l2 == l3) 1115 break; 1116 } 1117 if (l3 == NULL) { 1118 mutex_exit(p->p_lock); 1119 rw_exit(&p->p_reflock); 1120 error = EAGAIN; 1121 goto cleanup; 1122 } 1123 dp += elem_size; 1124 buflen -= elem_size; 1125 elem_count--; 1126 } 1127 needed += elem_size; 1128 } 1129 mutex_exit(p->p_lock); 1130 1131 /* Drop reference to process. */ 1132 mutex_enter(&proc_lock); 1133 rw_exit(&p->p_reflock); 1134 } 1135 mutex_exit(&proc_lock); 1136 } else { 1137 mutex_enter(&proc_lock); 1138 p = proc_find(pid); 1139 if (p == NULL) { 1140 error = ESRCH; 1141 mutex_exit(&proc_lock); 1142 goto cleanup; 1143 } 1144 /* Grab a hold on the process. */ 1145 gotit = rw_tryenter(&p->p_reflock, RW_READER); 1146 mutex_exit(&proc_lock); 1147 if (!gotit) { 1148 error = ESRCH; 1149 goto cleanup; 1150 } 1151 1152 mutex_enter(p->p_lock); 1153 LIST_FOREACH(l2, &p->p_lwps, l_sibling) { 1154 if (buflen >= elem_size && elem_count > 0) { 1155 lwp_lock(l2); 1156 fill_lwp(l2, &klwp); 1157 lwp_unlock(l2); 1158 mutex_exit(p->p_lock); 1159 /* 1160 * Copy out elem_size, but not larger than 1161 * the size of a struct kinfo_proc2. 1162 */ 1163 error = dcopyout(l, &klwp, dp, 1164 uimin(sizeof(klwp), elem_size)); 1165 if (error) { 1166 rw_exit(&p->p_reflock); 1167 goto cleanup; 1168 } 1169 mutex_enter(p->p_lock); 1170 LIST_FOREACH(l3, &p->p_lwps, l_sibling) { 1171 if (l2 == l3) 1172 break; 1173 } 1174 if (l3 == NULL) { 1175 mutex_exit(p->p_lock); 1176 rw_exit(&p->p_reflock); 1177 error = EAGAIN; 1178 goto cleanup; 1179 } 1180 dp += elem_size; 1181 buflen -= elem_size; 1182 elem_count--; 1183 } 1184 needed += elem_size; 1185 } 1186 mutex_exit(p->p_lock); 1187 1188 /* Drop reference to process. */ 1189 rw_exit(&p->p_reflock); 1190 } 1191 1192 if (where != NULL) { 1193 *oldlenp = dp - where; 1194 if (needed > *oldlenp) { 1195 sysctl_relock(); 1196 return (ENOMEM); 1197 } 1198 } else { 1199 needed += KERN_LWPSLOP; 1200 *oldlenp = needed; 1201 } 1202 error = 0; 1203 cleanup: 1204 sysctl_relock(); 1205 return (error); 1206 } 1207 1208 /* 1209 * sysctl helper routine for kern.forkfsleep node. Ensures that the 1210 * given value is not too large or two small, and is at least one 1211 * timer tick if not zero. 1212 */ 1213 static int 1214 sysctl_kern_forkfsleep(SYSCTLFN_ARGS) 1215 { 1216 /* userland sees value in ms, internally is in ticks */ 1217 extern int forkfsleep; /* defined in kern/kern_fork.c */ 1218 int error, timo, lsleep; 1219 struct sysctlnode node; 1220 1221 lsleep = forkfsleep * 1000 / hz; 1222 node = *rnode; 1223 node.sysctl_data = &lsleep; 1224 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 1225 if (error || newp == NULL) 1226 return (error); 1227 1228 /* refuse negative values, and overly 'long time' */ 1229 if (lsleep < 0 || lsleep > MAXSLP * 1000) 1230 return (EINVAL); 1231 1232 timo = mstohz(lsleep); 1233 1234 /* if the interval is >0 ms && <1 tick, use 1 tick */ 1235 if (lsleep != 0 && timo == 0) 1236 forkfsleep = 1; 1237 else 1238 forkfsleep = timo; 1239 1240 return (0); 1241 } 1242 1243 /* 1244 * sysctl helper routine for kern.root_partition 1245 */ 1246 static int 1247 sysctl_kern_root_partition(SYSCTLFN_ARGS) 1248 { 1249 int rootpart = DISKPART(rootdev); 1250 struct sysctlnode node = *rnode; 1251 1252 node.sysctl_data = &rootpart; 1253 return (sysctl_lookup(SYSCTLFN_CALL(&node))); 1254 } 1255 1256 /* 1257 * sysctl helper function for kern.drivers 1258 */ 1259 static int 1260 sysctl_kern_drivers(SYSCTLFN_ARGS) 1261 { 1262 int error; 1263 size_t buflen; 1264 struct kinfo_drivers kd; 1265 char *start, *where; 1266 const char *dname; 1267 int i; 1268 extern struct devsw_conv *devsw_conv; 1269 extern int max_devsw_convs; 1270 1271 start = where = oldp; 1272 buflen = *oldlenp; 1273 if (where == NULL) { 1274 *oldlenp = max_devsw_convs * sizeof kd; 1275 return 0; 1276 } 1277 1278 /* 1279 * An array of kinfo_drivers structures 1280 */ 1281 error = 0; 1282 sysctl_unlock(); 1283 mutex_enter(&device_lock); 1284 for (i = 0; i < max_devsw_convs; i++) { 1285 dname = devsw_conv[i].d_name; 1286 if (dname == NULL) 1287 continue; 1288 if (buflen < sizeof kd) { 1289 error = ENOMEM; 1290 break; 1291 } 1292 memset(&kd, 0, sizeof(kd)); 1293 kd.d_bmajor = devsw_conv[i].d_bmajor; 1294 kd.d_cmajor = devsw_conv[i].d_cmajor; 1295 strlcpy(kd.d_name, dname, sizeof kd.d_name); 1296 mutex_exit(&device_lock); 1297 error = dcopyout(l, &kd, where, sizeof kd); 1298 mutex_enter(&device_lock); 1299 if (error != 0) 1300 break; 1301 buflen -= sizeof kd; 1302 where += sizeof kd; 1303 } 1304 mutex_exit(&device_lock); 1305 sysctl_relock(); 1306 *oldlenp = where - start; 1307 return error; 1308 } 1309 1310 static int 1311 sysctl_security_setidcore(SYSCTLFN_ARGS) 1312 { 1313 int newsize, error; 1314 struct sysctlnode node; 1315 1316 node = *rnode; 1317 node.sysctl_data = &newsize; 1318 newsize = *(int *)rnode->sysctl_data; 1319 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 1320 if (error || newp == NULL) 1321 return error; 1322 1323 if (kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_SETIDCORE, 1324 0, NULL, NULL, NULL)) 1325 return (EPERM); 1326 1327 *(int *)rnode->sysctl_data = newsize; 1328 1329 return 0; 1330 } 1331 1332 static int 1333 sysctl_security_setidcorename(SYSCTLFN_ARGS) 1334 { 1335 int error; 1336 char *newsetidcorename; 1337 struct sysctlnode node; 1338 1339 newsetidcorename = PNBUF_GET(); 1340 node = *rnode; 1341 node.sysctl_data = newsetidcorename; 1342 memcpy(node.sysctl_data, rnode->sysctl_data, MAXPATHLEN); 1343 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 1344 if (error || newp == NULL) { 1345 goto out; 1346 } 1347 if (kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_SETIDCORE, 1348 0, NULL, NULL, NULL)) { 1349 error = EPERM; 1350 goto out; 1351 } 1352 if (strlen(newsetidcorename) == 0) { 1353 error = EINVAL; 1354 goto out; 1355 } 1356 memcpy(rnode->sysctl_data, node.sysctl_data, MAXPATHLEN); 1357 out: 1358 PNBUF_PUT(newsetidcorename); 1359 return error; 1360 } 1361 1362 /* 1363 * sysctl helper routine for kern.cp_id node. Maps cpus to their 1364 * cpuids. 1365 */ 1366 static int 1367 sysctl_kern_cpid(SYSCTLFN_ARGS) 1368 { 1369 struct sysctlnode node = *rnode; 1370 uint64_t *cp_id = NULL; 1371 int error, n = ncpu; 1372 struct cpu_info *ci; 1373 CPU_INFO_ITERATOR cii; 1374 1375 /* 1376 * Here you may either retrieve a single cpu id or the whole 1377 * set. The size you get back when probing depends on what 1378 * you ask for. 1379 */ 1380 switch (namelen) { 1381 case 0: 1382 node.sysctl_size = n * sizeof(uint64_t); 1383 n = -2; /* ALL */ 1384 break; 1385 case 1: 1386 if (name[0] < 0 || name[0] >= n) 1387 return (ENOENT); /* ENOSUCHPROCESSOR */ 1388 node.sysctl_size = sizeof(uint64_t); 1389 n = name[0]; 1390 /* 1391 * adjust these so that sysctl_lookup() will be happy 1392 */ 1393 name++; 1394 namelen--; 1395 break; 1396 default: 1397 return (EINVAL); 1398 } 1399 1400 cp_id = kmem_alloc(node.sysctl_size, KM_SLEEP); 1401 node.sysctl_data = cp_id; 1402 memset(cp_id, 0, node.sysctl_size); 1403 1404 for (CPU_INFO_FOREACH(cii, ci)) { 1405 if (n <= 0) 1406 cp_id[0] = cpu_index(ci); 1407 /* 1408 * if a specific processor was requested and we just 1409 * did it, we're done here 1410 */ 1411 if (n == 0) 1412 break; 1413 /* 1414 * if doing "all", skip to next cp_id slot for next processor 1415 */ 1416 if (n == -2) 1417 cp_id++; 1418 /* 1419 * if we're doing a specific processor, we're one 1420 * processor closer 1421 */ 1422 if (n > 0) 1423 n--; 1424 } 1425 1426 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 1427 kmem_free(node.sysctl_data, node.sysctl_size); 1428 return (error); 1429 } 1430 1431 /* 1432 * sysctl helper routine for hw.usermem and hw.usermem64. Values are 1433 * calculate on the fly taking into account integer overflow and the 1434 * current wired count. 1435 */ 1436 static int 1437 sysctl_hw_usermem(SYSCTLFN_ARGS) 1438 { 1439 u_int ui; 1440 u_quad_t uq; 1441 struct sysctlnode node; 1442 1443 node = *rnode; 1444 switch (rnode->sysctl_num) { 1445 case HW_USERMEM: 1446 if ((ui = physmem - uvmexp.wired) > (UINT_MAX / PAGE_SIZE)) 1447 ui = UINT_MAX; 1448 else 1449 ui *= PAGE_SIZE; 1450 node.sysctl_data = &ui; 1451 break; 1452 case HW_USERMEM64: 1453 uq = (u_quad_t)(physmem - uvmexp.wired) * PAGE_SIZE; 1454 node.sysctl_data = &uq; 1455 break; 1456 default: 1457 return (EINVAL); 1458 } 1459 1460 return (sysctl_lookup(SYSCTLFN_CALL(&node))); 1461 } 1462 1463 /* 1464 * sysctl helper routine for kern.cnmagic node. Pulls the old value 1465 * out, encoded, and stuffs the new value in for decoding. 1466 */ 1467 static int 1468 sysctl_hw_cnmagic(SYSCTLFN_ARGS) 1469 { 1470 char magic[CNS_LEN]; 1471 int error; 1472 struct sysctlnode node; 1473 1474 if (oldp) 1475 cn_get_magic(magic, CNS_LEN); 1476 node = *rnode; 1477 node.sysctl_data = &magic[0]; 1478 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 1479 if (error || newp == NULL) 1480 return (error); 1481 1482 return (cn_set_magic(magic)); 1483 } 1484 1485 /* 1486 * ******************************************************************** 1487 * section 3: public helper routines that are used for more than one 1488 * node 1489 * ******************************************************************** 1490 */ 1491 1492 /* 1493 * sysctl helper routine for the kern.root_device node and some ports' 1494 * machdep.root_device nodes. 1495 */ 1496 int 1497 sysctl_root_device(SYSCTLFN_ARGS) 1498 { 1499 struct sysctlnode node; 1500 1501 node = *rnode; 1502 node.sysctl_data = __UNCONST(device_xname(root_device)); 1503 node.sysctl_size = strlen(device_xname(root_device)) + 1; 1504 return (sysctl_lookup(SYSCTLFN_CALL(&node))); 1505 } 1506 1507 /* 1508 * sysctl helper routine for kern.consdev, dependent on the current 1509 * state of the console. Also used for machdep.console_device on some 1510 * ports. 1511 */ 1512 int 1513 sysctl_consdev(SYSCTLFN_ARGS) 1514 { 1515 dev_t consdev; 1516 uint32_t oconsdev; 1517 struct sysctlnode node; 1518 1519 if (cn_tab != NULL) 1520 consdev = cn_tab->cn_dev; 1521 else 1522 consdev = NODEV; 1523 node = *rnode; 1524 switch (*oldlenp) { 1525 case sizeof(consdev): 1526 node.sysctl_data = &consdev; 1527 node.sysctl_size = sizeof(consdev); 1528 break; 1529 case sizeof(oconsdev): 1530 oconsdev = (uint32_t)consdev; 1531 node.sysctl_data = &oconsdev; 1532 node.sysctl_size = sizeof(oconsdev); 1533 break; 1534 default: 1535 return EINVAL; 1536 } 1537 return (sysctl_lookup(SYSCTLFN_CALL(&node))); 1538 } 1539 1540 /* 1541 * ******************************************************************** 1542 * section 4: support for some helpers 1543 * ******************************************************************** 1544 */ 1545 1546 1547 /* 1548 * Fill in a kinfo_lwp structure for the specified lwp. 1549 */ 1550 static void 1551 fill_lwp(struct lwp *l, struct kinfo_lwp *kl) 1552 { 1553 const bool allowaddr = get_expose_address(curproc); 1554 struct proc *p = l->l_proc; 1555 struct timeval tv; 1556 1557 KASSERT(lwp_locked(l, NULL)); 1558 1559 memset(kl, 0, sizeof(*kl)); 1560 1561 kl->l_forw = 0; 1562 kl->l_back = 0; 1563 COND_SET_VALUE(kl->l_laddr, PTRTOUINT64(l), allowaddr); 1564 COND_SET_VALUE(kl->l_addr, PTRTOUINT64(l->l_addr), allowaddr); 1565 kl->l_stat = l->l_stat; 1566 kl->l_lid = l->l_lid; 1567 kl->l_flag = L_INMEM; 1568 kl->l_flag |= sysctl_map_flags(sysctl_lwpprflagmap, l->l_prflag); 1569 kl->l_flag |= sysctl_map_flags(sysctl_lwpflagmap, l->l_flag); 1570 1571 kl->l_swtime = l->l_swtime; 1572 kl->l_slptime = l->l_slptime; 1573 if (l->l_stat == LSONPROC) 1574 kl->l_schedflags = l->l_cpu->ci_schedstate.spc_flags; 1575 else 1576 kl->l_schedflags = 0; 1577 kl->l_priority = lwp_eprio(l); 1578 kl->l_usrpri = l->l_priority; 1579 if (l->l_wchan) 1580 strncpy(kl->l_wmesg, l->l_wmesg, sizeof(kl->l_wmesg)); 1581 COND_SET_VALUE(kl->l_wchan, PTRTOUINT64(l->l_wchan), allowaddr); 1582 kl->l_cpuid = cpu_index(l->l_cpu); 1583 bintime2timeval(&l->l_rtime, &tv); 1584 kl->l_rtime_sec = tv.tv_sec; 1585 kl->l_rtime_usec = tv.tv_usec; 1586 kl->l_cpticks = l->l_cpticks; 1587 kl->l_pctcpu = l->l_pctcpu; 1588 kl->l_pid = p->p_pid; 1589 if (l->l_name == NULL) 1590 kl->l_name[0] = '\0'; 1591 else 1592 strlcpy(kl->l_name, l->l_name, sizeof(kl->l_name)); 1593 } 1594