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