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