1 /* $NetBSD: init_sysctl.c,v 1.167 2009/09/16 15:03:56 pooka 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.167 2009/09/16 15:03:56 pooka Exp $"); 34 35 #include "opt_sysv.h" 36 #include "opt_compat_netbsd32.h" 37 #include "opt_compat_netbsd.h" 38 #include "opt_modular.h" 39 #include "opt_sa.h" 40 #include "opt_posix.h" 41 #include "pty.h" 42 #include "rnd.h" 43 44 #include <sys/types.h> 45 #include <sys/param.h> 46 #include <sys/sysctl.h> 47 #include <sys/cpu.h> 48 #include <sys/errno.h> 49 #include <sys/systm.h> 50 #include <sys/kernel.h> 51 #include <sys/unistd.h> 52 #include <sys/disklabel.h> 53 #include <sys/rnd.h> 54 #include <sys/vnode.h> 55 #include <sys/mount.h> 56 #include <sys/namei.h> 57 #include <sys/msgbuf.h> 58 #include <dev/cons.h> 59 #include <sys/socketvar.h> 60 #include <sys/file.h> 61 #include <sys/filedesc.h> 62 #include <sys/tty.h> 63 #include <sys/kmem.h> 64 #include <sys/resource.h> 65 #include <sys/resourcevar.h> 66 #include <sys/exec.h> 67 #include <sys/conf.h> 68 #include <sys/device.h> 69 #include <sys/stat.h> 70 #include <sys/kauth.h> 71 #include <sys/ktrace.h> 72 #include <sys/ksem.h> 73 74 #ifdef COMPAT_NETBSD32 75 #include <compat/netbsd32/netbsd32.h> 76 #endif 77 #ifdef COMPAT_50 78 #include <compat/sys/time.h> 79 #endif 80 81 #ifdef KERN_SA 82 #include <sys/sa.h> 83 #endif 84 85 #include <sys/cpu.h> 86 87 #if defined(MODULAR) || defined(P1003_1B_SEMAPHORE) 88 int posix_semaphores = 200112; 89 #else 90 int posix_semaphores; 91 #endif 92 93 int security_setidcore_dump; 94 char security_setidcore_path[MAXPATHLEN] = "/var/crash/%n.core"; 95 uid_t security_setidcore_owner = 0; 96 gid_t security_setidcore_group = 0; 97 mode_t security_setidcore_mode = (S_IRUSR|S_IWUSR); 98 99 static const u_int sysctl_flagmap[] = { 100 PK_ADVLOCK, P_ADVLOCK, 101 PK_EXEC, P_EXEC, 102 PK_NOCLDWAIT, P_NOCLDWAIT, 103 PK_32, P_32, 104 PK_CLDSIGIGN, P_CLDSIGIGN, 105 PK_SUGID, P_SUGID, 106 0 107 }; 108 109 static const u_int sysctl_sflagmap[] = { 110 PS_NOCLDSTOP, P_NOCLDSTOP, 111 PS_WEXIT, P_WEXIT, 112 PS_STOPFORK, P_STOPFORK, 113 PS_STOPEXEC, P_STOPEXEC, 114 PS_STOPEXIT, P_STOPEXIT, 115 0 116 }; 117 118 static const u_int sysctl_slflagmap[] = { 119 PSL_TRACED, P_TRACED, 120 PSL_FSTRACE, P_FSTRACE, 121 PSL_CHTRACED, P_CHTRACED, 122 PSL_SYSCALL, P_SYSCALL, 123 0 124 }; 125 126 static const u_int sysctl_lflagmap[] = { 127 PL_CONTROLT, P_CONTROLT, 128 PL_PPWAIT, P_PPWAIT, 129 0 130 }; 131 132 static const u_int sysctl_stflagmap[] = { 133 PST_PROFIL, P_PROFIL, 134 0 135 136 }; 137 138 static const u_int sysctl_lwpflagmap[] = { 139 LW_INMEM, P_INMEM, 140 LW_SINTR, P_SINTR, 141 LW_SYSTEM, P_SYSTEM, 142 LW_SA, P_SA, /* WRS ??? */ 143 0 144 }; 145 146 static const u_int sysctl_lwpprflagmap[] = { 147 LPR_DETACHED, L_DETACHED, 148 0 149 }; 150 151 /* 152 * try over estimating by 5 procs/lwps 153 */ 154 #define KERN_PROCSLOP (5 * sizeof(struct kinfo_proc)) 155 #define KERN_LWPSLOP (5 * sizeof(struct kinfo_lwp)) 156 157 static int dcopyout(struct lwp *, const void *, void *, size_t); 158 159 static int 160 dcopyout(struct lwp *l, const void *kaddr, void *uaddr, size_t len) 161 { 162 int error; 163 164 error = copyout(kaddr, uaddr, len); 165 ktrmibio(-1, UIO_READ, uaddr, len, error); 166 167 return error; 168 } 169 170 #ifdef DIAGNOSTIC 171 static int sysctl_kern_trigger_panic(SYSCTLFN_PROTO); 172 #endif 173 static int sysctl_kern_maxvnodes(SYSCTLFN_PROTO); 174 static int sysctl_kern_rtc_offset(SYSCTLFN_PROTO); 175 static int sysctl_kern_maxproc(SYSCTLFN_PROTO); 176 static int sysctl_kern_hostid(SYSCTLFN_PROTO); 177 static int sysctl_setlen(SYSCTLFN_PROTO); 178 static int sysctl_kern_clockrate(SYSCTLFN_PROTO); 179 static int sysctl_kern_file(SYSCTLFN_PROTO); 180 static int sysctl_msgbuf(SYSCTLFN_PROTO); 181 static int sysctl_kern_defcorename(SYSCTLFN_PROTO); 182 static int sysctl_kern_cptime(SYSCTLFN_PROTO); 183 #if NPTY > 0 184 static int sysctl_kern_maxptys(SYSCTLFN_PROTO); 185 #endif /* NPTY > 0 */ 186 static int sysctl_kern_sbmax(SYSCTLFN_PROTO); 187 static int sysctl_kern_urnd(SYSCTLFN_PROTO); 188 static int sysctl_kern_arnd(SYSCTLFN_PROTO); 189 static int sysctl_kern_lwp(SYSCTLFN_PROTO); 190 static int sysctl_kern_forkfsleep(SYSCTLFN_PROTO); 191 static int sysctl_kern_root_partition(SYSCTLFN_PROTO); 192 static int sysctl_kern_drivers(SYSCTLFN_PROTO); 193 static int sysctl_kern_file2(SYSCTLFN_PROTO); 194 static int sysctl_security_setidcore(SYSCTLFN_PROTO); 195 static int sysctl_security_setidcorename(SYSCTLFN_PROTO); 196 static int sysctl_kern_cpid(SYSCTLFN_PROTO); 197 static int sysctl_doeproc(SYSCTLFN_PROTO); 198 static int sysctl_kern_proc_args(SYSCTLFN_PROTO); 199 static int sysctl_hw_usermem(SYSCTLFN_PROTO); 200 static int sysctl_hw_cnmagic(SYSCTLFN_PROTO); 201 202 static u_int sysctl_map_flags(const u_int *, u_int); 203 static void fill_kproc2(struct proc *, struct kinfo_proc2 *, bool); 204 static void fill_lwp(struct lwp *l, struct kinfo_lwp *kl); 205 static void fill_file(struct kinfo_file *, const file_t *, const fdfile_t *, 206 int, pid_t); 207 208 /* 209 * ******************************************************************** 210 * section 1: setup routines 211 * ******************************************************************** 212 * These functions are stuffed into a link set for sysctl setup 213 * functions. They're never called or referenced from anywhere else. 214 * ******************************************************************** 215 */ 216 217 /* 218 * this setup routine is a replacement for kern_sysctl() 219 */ 220 SYSCTL_SETUP(sysctl_kern_setup, "sysctl kern subtree setup") 221 { 222 extern int kern_logsigexit; /* defined in kern/kern_sig.c */ 223 extern fixpt_t ccpu; /* defined in kern/kern_synch.c */ 224 extern int dumponpanic; /* defined in kern/subr_prf.c */ 225 const struct sysctlnode *rnode; 226 227 sysctl_createv(clog, 0, NULL, NULL, 228 CTLFLAG_PERMANENT, 229 CTLTYPE_NODE, "kern", NULL, 230 NULL, 0, NULL, 0, 231 CTL_KERN, CTL_EOL); 232 233 sysctl_createv(clog, 0, NULL, NULL, 234 CTLFLAG_PERMANENT, 235 CTLTYPE_STRING, "ostype", 236 SYSCTL_DESCR("Operating system type"), 237 NULL, 0, &ostype, 0, 238 CTL_KERN, KERN_OSTYPE, CTL_EOL); 239 sysctl_createv(clog, 0, NULL, NULL, 240 CTLFLAG_PERMANENT, 241 CTLTYPE_STRING, "osrelease", 242 SYSCTL_DESCR("Operating system release"), 243 NULL, 0, &osrelease, 0, 244 CTL_KERN, KERN_OSRELEASE, CTL_EOL); 245 sysctl_createv(clog, 0, NULL, NULL, 246 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 247 CTLTYPE_INT, "osrevision", 248 SYSCTL_DESCR("Operating system revision"), 249 NULL, __NetBSD_Version__, NULL, 0, 250 CTL_KERN, KERN_OSREV, CTL_EOL); 251 sysctl_createv(clog, 0, NULL, NULL, 252 CTLFLAG_PERMANENT, 253 CTLTYPE_STRING, "version", 254 SYSCTL_DESCR("Kernel version"), 255 NULL, 0, &version, 0, 256 CTL_KERN, KERN_VERSION, CTL_EOL); 257 sysctl_createv(clog, 0, NULL, NULL, 258 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 259 CTLTYPE_INT, "maxvnodes", 260 SYSCTL_DESCR("Maximum number of vnodes"), 261 sysctl_kern_maxvnodes, 0, NULL, 0, 262 CTL_KERN, KERN_MAXVNODES, CTL_EOL); 263 sysctl_createv(clog, 0, NULL, NULL, 264 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 265 CTLTYPE_INT, "maxproc", 266 SYSCTL_DESCR("Maximum number of simultaneous processes"), 267 sysctl_kern_maxproc, 0, NULL, 0, 268 CTL_KERN, KERN_MAXPROC, CTL_EOL); 269 sysctl_createv(clog, 0, NULL, NULL, 270 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 271 CTLTYPE_INT, "maxfiles", 272 SYSCTL_DESCR("Maximum number of open files"), 273 NULL, 0, &maxfiles, 0, 274 CTL_KERN, KERN_MAXFILES, CTL_EOL); 275 sysctl_createv(clog, 0, NULL, NULL, 276 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 277 CTLTYPE_INT, "argmax", 278 SYSCTL_DESCR("Maximum number of bytes of arguments to " 279 "execve(2)"), 280 NULL, ARG_MAX, NULL, 0, 281 CTL_KERN, KERN_ARGMAX, CTL_EOL); 282 sysctl_createv(clog, 0, NULL, NULL, 283 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 284 CTLTYPE_STRING, "hostname", 285 SYSCTL_DESCR("System hostname"), 286 sysctl_setlen, 0, &hostname, MAXHOSTNAMELEN, 287 CTL_KERN, KERN_HOSTNAME, CTL_EOL); 288 sysctl_createv(clog, 0, NULL, NULL, 289 CTLFLAG_PERMANENT|CTLFLAG_READWRITE|CTLFLAG_HEX, 290 CTLTYPE_INT, "hostid", 291 SYSCTL_DESCR("System host ID number"), 292 sysctl_kern_hostid, 0, NULL, 0, 293 CTL_KERN, KERN_HOSTID, CTL_EOL); 294 sysctl_createv(clog, 0, NULL, NULL, 295 CTLFLAG_PERMANENT, 296 CTLTYPE_STRUCT, "clockrate", 297 SYSCTL_DESCR("Kernel clock rates"), 298 sysctl_kern_clockrate, 0, NULL, 299 sizeof(struct clockinfo), 300 CTL_KERN, KERN_CLOCKRATE, CTL_EOL); 301 sysctl_createv(clog, 0, NULL, NULL, 302 CTLFLAG_PERMANENT, 303 CTLTYPE_INT, "hardclock_ticks", 304 SYSCTL_DESCR("Number of hardclock ticks"), 305 NULL, 0, &hardclock_ticks, sizeof(hardclock_ticks), 306 CTL_KERN, KERN_HARDCLOCK_TICKS, CTL_EOL); 307 sysctl_createv(clog, 0, NULL, NULL, 308 CTLFLAG_PERMANENT, 309 CTLTYPE_STRUCT, "vnode", 310 SYSCTL_DESCR("System vnode table"), 311 sysctl_kern_vnode, 0, NULL, 0, 312 CTL_KERN, KERN_VNODE, CTL_EOL); 313 sysctl_createv(clog, 0, NULL, NULL, 314 CTLFLAG_PERMANENT, 315 CTLTYPE_STRUCT, "file", 316 SYSCTL_DESCR("System open file table"), 317 sysctl_kern_file, 0, NULL, 0, 318 CTL_KERN, KERN_FILE, CTL_EOL); 319 #ifndef GPROF 320 sysctl_createv(clog, 0, NULL, NULL, 321 CTLFLAG_PERMANENT, 322 CTLTYPE_NODE, "profiling", 323 SYSCTL_DESCR("Profiling information (not available)"), 324 sysctl_notavail, 0, NULL, 0, 325 CTL_KERN, KERN_PROF, CTL_EOL); 326 #endif 327 sysctl_createv(clog, 0, NULL, NULL, 328 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 329 CTLTYPE_INT, "posix1version", 330 SYSCTL_DESCR("Version of ISO/IEC 9945 (POSIX 1003.1) " 331 "with which the operating system attempts " 332 "to comply"), 333 NULL, _POSIX_VERSION, NULL, 0, 334 CTL_KERN, KERN_POSIX1, CTL_EOL); 335 sysctl_createv(clog, 0, NULL, NULL, 336 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 337 CTLTYPE_INT, "ngroups", 338 SYSCTL_DESCR("Maximum number of supplemental groups"), 339 NULL, NGROUPS_MAX, NULL, 0, 340 CTL_KERN, KERN_NGROUPS, CTL_EOL); 341 sysctl_createv(clog, 0, NULL, NULL, 342 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 343 CTLTYPE_INT, "job_control", 344 SYSCTL_DESCR("Whether job control is available"), 345 NULL, 1, NULL, 0, 346 CTL_KERN, KERN_JOB_CONTROL, CTL_EOL); 347 sysctl_createv(clog, 0, NULL, NULL, 348 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 349 CTLTYPE_INT, "saved_ids", 350 SYSCTL_DESCR("Whether POSIX saved set-group/user ID is " 351 "available"), NULL, 352 #ifdef _POSIX_SAVED_IDS 353 1, 354 #else /* _POSIX_SAVED_IDS */ 355 0, 356 #endif /* _POSIX_SAVED_IDS */ 357 NULL, 0, CTL_KERN, KERN_SAVED_IDS, CTL_EOL); 358 sysctl_createv(clog, 0, NULL, NULL, 359 CTLFLAG_PERMANENT|CTLFLAG_HEX, 360 CTLTYPE_INT, "boothowto", 361 SYSCTL_DESCR("Flags from boot loader"), 362 NULL, 0, &boothowto, sizeof(boothowto), 363 CTL_KERN, CTL_CREATE, CTL_EOL); 364 sysctl_createv(clog, 0, NULL, NULL, 365 CTLFLAG_PERMANENT, 366 CTLTYPE_STRUCT, "boottime", 367 SYSCTL_DESCR("System boot time"), 368 NULL, 0, &boottime, sizeof(boottime), 369 CTL_KERN, KERN_BOOTTIME, CTL_EOL); 370 #ifdef COMPAT_50 371 { 372 extern struct timeval50 boottime50; 373 sysctl_createv(clog, 0, NULL, NULL, 374 CTLFLAG_PERMANENT, 375 CTLTYPE_STRUCT, "oboottime", 376 SYSCTL_DESCR("System boot time"), 377 NULL, 0, &boottime50, sizeof(boottime50), 378 CTL_KERN, KERN_OBOOTTIME, CTL_EOL); 379 } 380 #endif 381 sysctl_createv(clog, 0, NULL, NULL, 382 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 383 CTLTYPE_STRING, "domainname", 384 SYSCTL_DESCR("YP domain name"), 385 sysctl_setlen, 0, &domainname, MAXHOSTNAMELEN, 386 CTL_KERN, KERN_DOMAINNAME, CTL_EOL); 387 sysctl_createv(clog, 0, NULL, NULL, 388 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 389 CTLTYPE_INT, "maxpartitions", 390 SYSCTL_DESCR("Maximum number of partitions allowed per " 391 "disk"), 392 NULL, MAXPARTITIONS, NULL, 0, 393 CTL_KERN, KERN_MAXPARTITIONS, CTL_EOL); 394 sysctl_createv(clog, 0, NULL, NULL, 395 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 396 CTLTYPE_INT, "rawpartition", 397 SYSCTL_DESCR("Raw partition of a disk"), 398 NULL, RAW_PART, NULL, 0, 399 CTL_KERN, KERN_RAWPARTITION, CTL_EOL); 400 sysctl_createv(clog, 0, NULL, NULL, 401 CTLFLAG_PERMANENT, 402 CTLTYPE_STRUCT, "timex", NULL, 403 sysctl_notavail, 0, NULL, 0, 404 CTL_KERN, KERN_TIMEX, CTL_EOL); 405 sysctl_createv(clog, 0, NULL, NULL, 406 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 407 CTLTYPE_INT, "rtc_offset", 408 SYSCTL_DESCR("Offset of real time clock from UTC in " 409 "minutes"), 410 sysctl_kern_rtc_offset, 0, &rtc_offset, 0, 411 CTL_KERN, KERN_RTC_OFFSET, CTL_EOL); 412 sysctl_createv(clog, 0, NULL, NULL, 413 CTLFLAG_PERMANENT, 414 CTLTYPE_STRING, "root_device", 415 SYSCTL_DESCR("Name of the root device"), 416 sysctl_root_device, 0, NULL, 0, 417 CTL_KERN, KERN_ROOT_DEVICE, CTL_EOL); 418 sysctl_createv(clog, 0, NULL, NULL, 419 CTLFLAG_PERMANENT, 420 CTLTYPE_INT, "msgbufsize", 421 SYSCTL_DESCR("Size of the kernel message buffer"), 422 sysctl_msgbuf, 0, NULL, 0, 423 CTL_KERN, KERN_MSGBUFSIZE, CTL_EOL); 424 sysctl_createv(clog, 0, NULL, NULL, 425 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 426 CTLTYPE_INT, "fsync", 427 SYSCTL_DESCR("Whether the POSIX 1003.1b File " 428 "Synchronization Option is available on " 429 "this system"), 430 NULL, 1, NULL, 0, 431 CTL_KERN, KERN_FSYNC, CTL_EOL); 432 sysctl_createv(clog, 0, NULL, NULL, 433 CTLFLAG_PERMANENT, 434 CTLTYPE_NODE, "ipc", 435 SYSCTL_DESCR("SysV IPC options"), 436 NULL, 0, NULL, 0, 437 CTL_KERN, KERN_SYSVIPC, CTL_EOL); 438 sysctl_createv(clog, 0, NULL, NULL, 439 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 440 CTLTYPE_INT, "sysvmsg", 441 SYSCTL_DESCR("System V style message support available"), 442 NULL, 443 #ifdef SYSVMSG 444 1, 445 #else /* SYSVMSG */ 446 0, 447 #endif /* SYSVMSG */ 448 NULL, 0, CTL_KERN, KERN_SYSVIPC, KERN_SYSVIPC_MSG, CTL_EOL); 449 sysctl_createv(clog, 0, NULL, NULL, 450 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 451 CTLTYPE_INT, "sysvsem", 452 SYSCTL_DESCR("System V style semaphore support " 453 "available"), NULL, 454 #ifdef SYSVSEM 455 1, 456 #else /* SYSVSEM */ 457 0, 458 #endif /* SYSVSEM */ 459 NULL, 0, CTL_KERN, KERN_SYSVIPC, KERN_SYSVIPC_SEM, CTL_EOL); 460 sysctl_createv(clog, 0, NULL, NULL, 461 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 462 CTLTYPE_INT, "sysvshm", 463 SYSCTL_DESCR("System V style shared memory support " 464 "available"), NULL, 465 #ifdef SYSVSHM 466 1, 467 #else /* SYSVSHM */ 468 0, 469 #endif /* SYSVSHM */ 470 NULL, 0, CTL_KERN, KERN_SYSVIPC, KERN_SYSVIPC_SHM, CTL_EOL); 471 sysctl_createv(clog, 0, NULL, NULL, 472 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 473 CTLTYPE_INT, "synchronized_io", 474 SYSCTL_DESCR("Whether the POSIX 1003.1b Synchronized " 475 "I/O Option is available on this system"), 476 NULL, 1, NULL, 0, 477 CTL_KERN, KERN_SYNCHRONIZED_IO, CTL_EOL); 478 sysctl_createv(clog, 0, NULL, NULL, 479 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 480 CTLTYPE_INT, "iov_max", 481 SYSCTL_DESCR("Maximum number of iovec structures per " 482 "process"), 483 NULL, IOV_MAX, NULL, 0, 484 CTL_KERN, KERN_IOV_MAX, CTL_EOL); 485 sysctl_createv(clog, 0, NULL, NULL, 486 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 487 CTLTYPE_INT, "mapped_files", 488 SYSCTL_DESCR("Whether the POSIX 1003.1b Memory Mapped " 489 "Files Option is available on this system"), 490 NULL, 1, NULL, 0, 491 CTL_KERN, KERN_MAPPED_FILES, CTL_EOL); 492 sysctl_createv(clog, 0, NULL, NULL, 493 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 494 CTLTYPE_INT, "memlock", 495 SYSCTL_DESCR("Whether the POSIX 1003.1b Process Memory " 496 "Locking Option is available on this " 497 "system"), 498 NULL, 1, NULL, 0, 499 CTL_KERN, KERN_MEMLOCK, CTL_EOL); 500 sysctl_createv(clog, 0, NULL, NULL, 501 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 502 CTLTYPE_INT, "memlock_range", 503 SYSCTL_DESCR("Whether the POSIX 1003.1b Range Memory " 504 "Locking Option is available on this " 505 "system"), 506 NULL, 1, NULL, 0, 507 CTL_KERN, KERN_MEMLOCK_RANGE, CTL_EOL); 508 sysctl_createv(clog, 0, NULL, NULL, 509 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 510 CTLTYPE_INT, "memory_protection", 511 SYSCTL_DESCR("Whether the POSIX 1003.1b Memory " 512 "Protection Option is available on this " 513 "system"), 514 NULL, 1, NULL, 0, 515 CTL_KERN, KERN_MEMORY_PROTECTION, CTL_EOL); 516 sysctl_createv(clog, 0, NULL, NULL, 517 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 518 CTLTYPE_INT, "login_name_max", 519 SYSCTL_DESCR("Maximum login name length"), 520 NULL, LOGIN_NAME_MAX, NULL, 0, 521 CTL_KERN, KERN_LOGIN_NAME_MAX, CTL_EOL); 522 sysctl_createv(clog, 0, NULL, NULL, 523 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 524 CTLTYPE_STRING, "defcorename", 525 SYSCTL_DESCR("Default core file name"), 526 sysctl_kern_defcorename, 0, defcorename, MAXPATHLEN, 527 CTL_KERN, KERN_DEFCORENAME, CTL_EOL); 528 sysctl_createv(clog, 0, NULL, NULL, 529 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 530 CTLTYPE_INT, "logsigexit", 531 SYSCTL_DESCR("Log process exit when caused by signals"), 532 NULL, 0, &kern_logsigexit, 0, 533 CTL_KERN, KERN_LOGSIGEXIT, CTL_EOL); 534 sysctl_createv(clog, 0, NULL, NULL, 535 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 536 CTLTYPE_INT, "fscale", 537 SYSCTL_DESCR("Kernel fixed-point scale factor"), 538 NULL, FSCALE, NULL, 0, 539 CTL_KERN, KERN_FSCALE, CTL_EOL); 540 sysctl_createv(clog, 0, NULL, NULL, 541 CTLFLAG_PERMANENT, 542 CTLTYPE_INT, "ccpu", 543 SYSCTL_DESCR("Scheduler exponential decay value"), 544 NULL, 0, &ccpu, 0, 545 CTL_KERN, KERN_CCPU, CTL_EOL); 546 sysctl_createv(clog, 0, NULL, NULL, 547 CTLFLAG_PERMANENT, 548 CTLTYPE_STRUCT, "cp_time", 549 SYSCTL_DESCR("Clock ticks spent in different CPU states"), 550 sysctl_kern_cptime, 0, NULL, 0, 551 CTL_KERN, KERN_CP_TIME, CTL_EOL); 552 sysctl_createv(clog, 0, NULL, NULL, 553 CTLFLAG_PERMANENT, 554 CTLTYPE_INT, "msgbuf", 555 SYSCTL_DESCR("Kernel message buffer"), 556 sysctl_msgbuf, 0, NULL, 0, 557 CTL_KERN, KERN_MSGBUF, CTL_EOL); 558 sysctl_createv(clog, 0, NULL, NULL, 559 CTLFLAG_PERMANENT, 560 CTLTYPE_STRUCT, "consdev", 561 SYSCTL_DESCR("Console device"), 562 sysctl_consdev, 0, NULL, sizeof(dev_t), 563 CTL_KERN, KERN_CONSDEV, CTL_EOL); 564 #if NPTY > 0 565 sysctl_createv(clog, 0, NULL, NULL, 566 CTLFLAG_PERMANENT, 567 CTLTYPE_INT, "maxptys", 568 SYSCTL_DESCR("Maximum number of pseudo-ttys"), 569 sysctl_kern_maxptys, 0, NULL, 0, 570 CTL_KERN, KERN_MAXPTYS, CTL_EOL); 571 #endif /* NPTY > 0 */ 572 sysctl_createv(clog, 0, NULL, NULL, 573 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 574 CTLTYPE_INT, "maxphys", 575 SYSCTL_DESCR("Maximum raw I/O transfer size"), 576 NULL, MAXPHYS, NULL, 0, 577 CTL_KERN, KERN_MAXPHYS, CTL_EOL); 578 sysctl_createv(clog, 0, NULL, NULL, 579 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 580 CTLTYPE_INT, "sbmax", 581 SYSCTL_DESCR("Maximum socket buffer size"), 582 sysctl_kern_sbmax, 0, NULL, 0, 583 CTL_KERN, KERN_SBMAX, CTL_EOL); 584 sysctl_createv(clog, 0, NULL, NULL, 585 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 586 CTLTYPE_INT, "monotonic_clock", 587 SYSCTL_DESCR("Implementation version of the POSIX " 588 "1003.1b Monotonic Clock Option"), 589 /* XXX _POSIX_VERSION */ 590 NULL, _POSIX_MONOTONIC_CLOCK, NULL, 0, 591 CTL_KERN, KERN_MONOTONIC_CLOCK, CTL_EOL); 592 sysctl_createv(clog, 0, NULL, NULL, 593 CTLFLAG_PERMANENT, 594 CTLTYPE_INT, "urandom", 595 SYSCTL_DESCR("Random integer value"), 596 sysctl_kern_urnd, 0, NULL, 0, 597 CTL_KERN, KERN_URND, CTL_EOL); 598 sysctl_createv(clog, 0, NULL, NULL, 599 CTLFLAG_PERMANENT, 600 CTLTYPE_INT, "arandom", 601 SYSCTL_DESCR("n bytes of random data"), 602 sysctl_kern_arnd, 0, NULL, 0, 603 CTL_KERN, KERN_ARND, CTL_EOL); 604 sysctl_createv(clog, 0, NULL, NULL, 605 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 606 CTLTYPE_INT, "labelsector", 607 SYSCTL_DESCR("Sector number containing the disklabel"), 608 NULL, LABELSECTOR, NULL, 0, 609 CTL_KERN, KERN_LABELSECTOR, CTL_EOL); 610 sysctl_createv(clog, 0, NULL, NULL, 611 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 612 CTLTYPE_INT, "labeloffset", 613 SYSCTL_DESCR("Offset of the disklabel within the " 614 "sector"), 615 NULL, LABELOFFSET, NULL, 0, 616 CTL_KERN, KERN_LABELOFFSET, CTL_EOL); 617 sysctl_createv(clog, 0, NULL, NULL, 618 CTLFLAG_PERMANENT, 619 CTLTYPE_NODE, "lwp", 620 SYSCTL_DESCR("System-wide LWP information"), 621 sysctl_kern_lwp, 0, NULL, 0, 622 CTL_KERN, KERN_LWP, CTL_EOL); 623 sysctl_createv(clog, 0, NULL, NULL, 624 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 625 CTLTYPE_INT, "forkfsleep", 626 SYSCTL_DESCR("Milliseconds to sleep on fork failure due " 627 "to process limits"), 628 sysctl_kern_forkfsleep, 0, NULL, 0, 629 CTL_KERN, KERN_FORKFSLEEP, CTL_EOL); 630 sysctl_createv(clog, 0, NULL, NULL, 631 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 632 CTLTYPE_INT, "posix_threads", 633 SYSCTL_DESCR("Version of IEEE Std 1003.1 and its " 634 "Threads option to which the system " 635 "attempts to conform"), 636 /* XXX _POSIX_VERSION */ 637 NULL, _POSIX_THREADS, NULL, 0, 638 CTL_KERN, KERN_POSIX_THREADS, CTL_EOL); 639 sysctl_createv(clog, 0, NULL, NULL, 640 CTLFLAG_PERMANENT, 641 CTLTYPE_INT, "posix_semaphores", 642 SYSCTL_DESCR("Version of IEEE Std 1003.1 and its " 643 "Semaphores option to which the system " 644 "attempts to conform"), NULL, 645 0, &posix_semaphores, 646 0, CTL_KERN, KERN_POSIX_SEMAPHORES, CTL_EOL); 647 sysctl_createv(clog, 0, NULL, NULL, 648 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 649 CTLTYPE_INT, "posix_barriers", 650 SYSCTL_DESCR("Version of IEEE Std 1003.1 and its " 651 "Barriers option to which the system " 652 "attempts to conform"), 653 /* XXX _POSIX_VERSION */ 654 NULL, _POSIX_BARRIERS, NULL, 0, 655 CTL_KERN, KERN_POSIX_BARRIERS, CTL_EOL); 656 sysctl_createv(clog, 0, NULL, NULL, 657 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 658 CTLTYPE_INT, "posix_timers", 659 SYSCTL_DESCR("Version of IEEE Std 1003.1 and its " 660 "Timers option to which the system " 661 "attempts to conform"), 662 /* XXX _POSIX_VERSION */ 663 NULL, _POSIX_TIMERS, NULL, 0, 664 CTL_KERN, KERN_POSIX_TIMERS, CTL_EOL); 665 sysctl_createv(clog, 0, NULL, NULL, 666 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 667 CTLTYPE_INT, "posix_spin_locks", 668 SYSCTL_DESCR("Version of IEEE Std 1003.1 and its Spin " 669 "Locks option to which the system attempts " 670 "to conform"), 671 /* XXX _POSIX_VERSION */ 672 NULL, _POSIX_SPIN_LOCKS, NULL, 0, 673 CTL_KERN, KERN_POSIX_SPIN_LOCKS, CTL_EOL); 674 sysctl_createv(clog, 0, NULL, NULL, 675 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 676 CTLTYPE_INT, "posix_reader_writer_locks", 677 SYSCTL_DESCR("Version of IEEE Std 1003.1 and its " 678 "Read-Write Locks option to which the " 679 "system attempts to conform"), 680 /* XXX _POSIX_VERSION */ 681 NULL, _POSIX_READER_WRITER_LOCKS, NULL, 0, 682 CTL_KERN, KERN_POSIX_READER_WRITER_LOCKS, CTL_EOL); 683 sysctl_createv(clog, 0, NULL, NULL, 684 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 685 CTLTYPE_INT, "dump_on_panic", 686 SYSCTL_DESCR("Perform a crash dump on system panic"), 687 NULL, 0, &dumponpanic, 0, 688 CTL_KERN, KERN_DUMP_ON_PANIC, CTL_EOL); 689 #ifdef DIAGNOSTIC 690 sysctl_createv(clog, 0, NULL, NULL, 691 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 692 CTLTYPE_INT, "panic_now", 693 SYSCTL_DESCR("Trigger a panic"), 694 sysctl_kern_trigger_panic, 0, NULL, 0, 695 CTL_KERN, CTL_CREATE, CTL_EOL); 696 #endif 697 sysctl_createv(clog, 0, NULL, NULL, 698 CTLFLAG_PERMANENT, 699 CTLTYPE_INT, "root_partition", 700 SYSCTL_DESCR("Root partition on the root device"), 701 sysctl_kern_root_partition, 0, NULL, 0, 702 CTL_KERN, KERN_ROOT_PARTITION, CTL_EOL); 703 sysctl_createv(clog, 0, NULL, NULL, 704 CTLFLAG_PERMANENT, 705 CTLTYPE_STRUCT, "drivers", 706 SYSCTL_DESCR("List of all drivers with block and " 707 "character device numbers"), 708 sysctl_kern_drivers, 0, NULL, 0, 709 CTL_KERN, KERN_DRIVERS, CTL_EOL); 710 sysctl_createv(clog, 0, NULL, NULL, 711 CTLFLAG_PERMANENT, 712 CTLTYPE_STRUCT, "file2", 713 SYSCTL_DESCR("System open file table"), 714 sysctl_kern_file2, 0, NULL, 0, 715 CTL_KERN, KERN_FILE2, CTL_EOL); 716 sysctl_createv(clog, 0, NULL, NULL, 717 CTLFLAG_PERMANENT, 718 CTLTYPE_STRUCT, "cp_id", 719 SYSCTL_DESCR("Mapping of CPU number to CPU id"), 720 sysctl_kern_cpid, 0, NULL, 0, 721 CTL_KERN, KERN_CP_ID, CTL_EOL); 722 sysctl_createv(clog, 0, NULL, &rnode, 723 CTLFLAG_PERMANENT, 724 CTLTYPE_NODE, "coredump", 725 SYSCTL_DESCR("Coredump settings."), 726 NULL, 0, NULL, 0, 727 CTL_KERN, CTL_CREATE, CTL_EOL); 728 sysctl_createv(clog, 0, &rnode, &rnode, 729 CTLFLAG_PERMANENT, 730 CTLTYPE_NODE, "setid", 731 SYSCTL_DESCR("Set-id processes' coredump settings."), 732 NULL, 0, NULL, 0, 733 CTL_CREATE, CTL_EOL); 734 sysctl_createv(clog, 0, &rnode, NULL, 735 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 736 CTLTYPE_INT, "dump", 737 SYSCTL_DESCR("Allow set-id processes to dump core."), 738 sysctl_security_setidcore, 0, &security_setidcore_dump, 739 sizeof(security_setidcore_dump), 740 CTL_CREATE, CTL_EOL); 741 sysctl_createv(clog, 0, &rnode, NULL, 742 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 743 CTLTYPE_STRING, "path", 744 SYSCTL_DESCR("Path pattern for set-id coredumps."), 745 sysctl_security_setidcorename, 0, 746 &security_setidcore_path, 747 sizeof(security_setidcore_path), 748 CTL_CREATE, CTL_EOL); 749 sysctl_createv(clog, 0, &rnode, NULL, 750 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 751 CTLTYPE_INT, "owner", 752 SYSCTL_DESCR("Owner id for set-id processes' cores."), 753 sysctl_security_setidcore, 0, &security_setidcore_owner, 754 0, 755 CTL_CREATE, CTL_EOL); 756 sysctl_createv(clog, 0, &rnode, NULL, 757 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 758 CTLTYPE_INT, "group", 759 SYSCTL_DESCR("Group id for set-id processes' cores."), 760 sysctl_security_setidcore, 0, &security_setidcore_group, 761 0, 762 CTL_CREATE, CTL_EOL); 763 sysctl_createv(clog, 0, &rnode, NULL, 764 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 765 CTLTYPE_INT, "mode", 766 SYSCTL_DESCR("Mode for set-id processes' cores."), 767 sysctl_security_setidcore, 0, &security_setidcore_mode, 768 0, 769 CTL_CREATE, CTL_EOL); 770 #ifdef KERN_SA 771 sysctl_createv(clog, 0, NULL, NULL, 772 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 773 CTLTYPE_INT, "no_sa_support", 774 SYSCTL_DESCR("0 if the kernel supports SA, otherwise it doesn't"), 775 NULL, 0, &sa_system_disabled, 0, 776 CTL_KERN, CTL_CREATE, CTL_EOL); 777 #else 778 sysctl_createv(clog, 0, NULL, NULL, 779 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 780 CTLTYPE_INT, "no_sa_support", 781 SYSCTL_DESCR("0 if the kernel supports SA, otherwise it doesn't"), 782 NULL, 1, NULL, 0, 783 CTL_KERN, CTL_CREATE, CTL_EOL); 784 #endif 785 786 /* kern.posix. */ 787 sysctl_createv(clog, 0, NULL, &rnode, 788 CTLFLAG_PERMANENT, 789 CTLTYPE_NODE, "posix", 790 SYSCTL_DESCR("POSIX options"), 791 NULL, 0, NULL, 0, 792 CTL_KERN, CTL_CREATE, CTL_EOL); 793 sysctl_createv(clog, 0, &rnode, NULL, 794 CTLFLAG_PERMANENT | CTLFLAG_READWRITE, 795 CTLTYPE_INT, "semmax", 796 SYSCTL_DESCR("Maximal number of semaphores"), 797 NULL, 0, &ksem_max, 0, 798 CTL_CREATE, CTL_EOL); 799 } 800 801 SYSCTL_SETUP(sysctl_kern_proc_setup, 802 "sysctl kern.proc/proc2/proc_args subtree setup") 803 { 804 805 sysctl_createv(clog, 0, NULL, NULL, 806 CTLFLAG_PERMANENT, 807 CTLTYPE_NODE, "kern", NULL, 808 NULL, 0, NULL, 0, 809 CTL_KERN, CTL_EOL); 810 811 sysctl_createv(clog, 0, NULL, NULL, 812 CTLFLAG_PERMANENT, 813 CTLTYPE_NODE, "proc", 814 SYSCTL_DESCR("System-wide process information"), 815 sysctl_doeproc, 0, NULL, 0, 816 CTL_KERN, KERN_PROC, CTL_EOL); 817 sysctl_createv(clog, 0, NULL, NULL, 818 CTLFLAG_PERMANENT, 819 CTLTYPE_NODE, "proc2", 820 SYSCTL_DESCR("Machine-independent process information"), 821 sysctl_doeproc, 0, NULL, 0, 822 CTL_KERN, KERN_PROC2, CTL_EOL); 823 sysctl_createv(clog, 0, NULL, NULL, 824 CTLFLAG_PERMANENT, 825 CTLTYPE_NODE, "proc_args", 826 SYSCTL_DESCR("Process argument information"), 827 sysctl_kern_proc_args, 0, NULL, 0, 828 CTL_KERN, KERN_PROC_ARGS, CTL_EOL); 829 830 /* 831 "nodes" under these: 832 833 KERN_PROC_ALL 834 KERN_PROC_PID pid 835 KERN_PROC_PGRP pgrp 836 KERN_PROC_SESSION sess 837 KERN_PROC_TTY tty 838 KERN_PROC_UID uid 839 KERN_PROC_RUID uid 840 KERN_PROC_GID gid 841 KERN_PROC_RGID gid 842 843 all in all, probably not worth the effort... 844 */ 845 } 846 847 SYSCTL_SETUP(sysctl_hw_setup, "sysctl hw subtree setup") 848 { 849 u_int u; 850 u_quad_t q; 851 852 sysctl_createv(clog, 0, NULL, NULL, 853 CTLFLAG_PERMANENT, 854 CTLTYPE_NODE, "hw", NULL, 855 NULL, 0, NULL, 0, 856 CTL_HW, CTL_EOL); 857 858 sysctl_createv(clog, 0, NULL, NULL, 859 CTLFLAG_PERMANENT, 860 CTLTYPE_STRING, "machine", 861 SYSCTL_DESCR("Machine class"), 862 NULL, 0, machine, 0, 863 CTL_HW, HW_MACHINE, CTL_EOL); 864 sysctl_createv(clog, 0, NULL, NULL, 865 CTLFLAG_PERMANENT, 866 CTLTYPE_STRING, "model", 867 SYSCTL_DESCR("Machine model"), 868 NULL, 0, cpu_model, 0, 869 CTL_HW, HW_MODEL, CTL_EOL); 870 sysctl_createv(clog, 0, NULL, NULL, 871 CTLFLAG_PERMANENT, 872 CTLTYPE_INT, "ncpu", 873 SYSCTL_DESCR("Number of CPUs configured"), 874 NULL, 0, &ncpu, 0, 875 CTL_HW, HW_NCPU, CTL_EOL); 876 sysctl_createv(clog, 0, NULL, NULL, 877 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 878 CTLTYPE_INT, "byteorder", 879 SYSCTL_DESCR("System byte order"), 880 NULL, BYTE_ORDER, NULL, 0, 881 CTL_HW, HW_BYTEORDER, CTL_EOL); 882 u = ((u_int)physmem > (UINT_MAX / PAGE_SIZE)) ? 883 UINT_MAX : physmem * PAGE_SIZE; 884 sysctl_createv(clog, 0, NULL, NULL, 885 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 886 CTLTYPE_INT, "physmem", 887 SYSCTL_DESCR("Bytes of physical memory"), 888 NULL, u, NULL, 0, 889 CTL_HW, HW_PHYSMEM, CTL_EOL); 890 sysctl_createv(clog, 0, NULL, NULL, 891 CTLFLAG_PERMANENT, 892 CTLTYPE_INT, "usermem", 893 SYSCTL_DESCR("Bytes of non-kernel memory"), 894 sysctl_hw_usermem, 0, NULL, 0, 895 CTL_HW, HW_USERMEM, CTL_EOL); 896 sysctl_createv(clog, 0, NULL, NULL, 897 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 898 CTLTYPE_INT, "pagesize", 899 SYSCTL_DESCR("Software page size"), 900 NULL, PAGE_SIZE, NULL, 0, 901 CTL_HW, HW_PAGESIZE, CTL_EOL); 902 sysctl_createv(clog, 0, NULL, NULL, 903 CTLFLAG_PERMANENT, 904 CTLTYPE_STRING, "machine_arch", 905 SYSCTL_DESCR("Machine CPU class"), 906 NULL, 0, machine_arch, 0, 907 CTL_HW, HW_MACHINE_ARCH, CTL_EOL); 908 sysctl_createv(clog, 0, NULL, NULL, 909 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 910 CTLTYPE_INT, "alignbytes", 911 SYSCTL_DESCR("Alignment constraint for all possible " 912 "data types"), 913 NULL, ALIGNBYTES, NULL, 0, 914 CTL_HW, HW_ALIGNBYTES, CTL_EOL); 915 sysctl_createv(clog, 0, NULL, NULL, 916 CTLFLAG_PERMANENT|CTLFLAG_READWRITE|CTLFLAG_HEX, 917 CTLTYPE_STRING, "cnmagic", 918 SYSCTL_DESCR("Console magic key sequence"), 919 sysctl_hw_cnmagic, 0, NULL, CNS_LEN, 920 CTL_HW, HW_CNMAGIC, CTL_EOL); 921 q = (u_quad_t)physmem * PAGE_SIZE; 922 sysctl_createv(clog, 0, NULL, NULL, 923 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 924 CTLTYPE_QUAD, "physmem64", 925 SYSCTL_DESCR("Bytes of physical memory"), 926 NULL, q, NULL, 0, 927 CTL_HW, HW_PHYSMEM64, CTL_EOL); 928 sysctl_createv(clog, 0, NULL, NULL, 929 CTLFLAG_PERMANENT, 930 CTLTYPE_QUAD, "usermem64", 931 SYSCTL_DESCR("Bytes of non-kernel memory"), 932 sysctl_hw_usermem, 0, NULL, 0, 933 CTL_HW, HW_USERMEM64, CTL_EOL); 934 sysctl_createv(clog, 0, NULL, NULL, 935 CTLFLAG_PERMANENT, 936 CTLTYPE_INT, "ncpuonline", 937 SYSCTL_DESCR("Number of CPUs online"), 938 NULL, 0, &ncpuonline, 0, 939 CTL_HW, HW_NCPUONLINE, CTL_EOL); 940 } 941 942 #ifdef DEBUG 943 /* 944 * Debugging related system variables. 945 */ 946 struct ctldebug /* debug0, */ /* debug1, */ debug2, debug3, debug4; 947 struct ctldebug debug5, debug6, debug7, debug8, debug9; 948 struct ctldebug debug10, debug11, debug12, debug13, debug14; 949 struct ctldebug debug15, debug16, debug17, debug18, debug19; 950 static struct ctldebug *debugvars[CTL_DEBUG_MAXID] = { 951 &debug0, &debug1, &debug2, &debug3, &debug4, 952 &debug5, &debug6, &debug7, &debug8, &debug9, 953 &debug10, &debug11, &debug12, &debug13, &debug14, 954 &debug15, &debug16, &debug17, &debug18, &debug19, 955 }; 956 957 /* 958 * this setup routine is a replacement for debug_sysctl() 959 * 960 * note that it creates several nodes per defined debug variable 961 */ 962 SYSCTL_SETUP(sysctl_debug_setup, "sysctl debug subtree setup") 963 { 964 struct ctldebug *cdp; 965 char nodename[20]; 966 int i; 967 968 /* 969 * two ways here: 970 * 971 * the "old" way (debug.name -> value) which was emulated by 972 * the sysctl(8) binary 973 * 974 * the new way, which the sysctl(8) binary was actually using 975 976 node debug 977 node debug.0 978 string debug.0.name 979 int debug.0.value 980 int debug.name 981 982 */ 983 984 sysctl_createv(clog, 0, NULL, NULL, 985 CTLFLAG_PERMANENT, 986 CTLTYPE_NODE, "debug", NULL, 987 NULL, 0, NULL, 0, 988 CTL_DEBUG, CTL_EOL); 989 990 for (i = 0; i < CTL_DEBUG_MAXID; i++) { 991 cdp = debugvars[i]; 992 if (cdp->debugname == NULL || cdp->debugvar == NULL) 993 continue; 994 995 snprintf(nodename, sizeof(nodename), "debug%d", i); 996 sysctl_createv(clog, 0, NULL, NULL, 997 CTLFLAG_PERMANENT|CTLFLAG_HIDDEN, 998 CTLTYPE_NODE, nodename, NULL, 999 NULL, 0, NULL, 0, 1000 CTL_DEBUG, i, CTL_EOL); 1001 sysctl_createv(clog, 0, NULL, NULL, 1002 CTLFLAG_PERMANENT|CTLFLAG_HIDDEN, 1003 CTLTYPE_STRING, "name", NULL, 1004 /*XXXUNCONST*/ 1005 NULL, 0, __UNCONST(cdp->debugname), 0, 1006 CTL_DEBUG, i, CTL_DEBUG_NAME, CTL_EOL); 1007 sysctl_createv(clog, 0, NULL, NULL, 1008 CTLFLAG_PERMANENT|CTLFLAG_HIDDEN, 1009 CTLTYPE_INT, "value", NULL, 1010 NULL, 0, cdp->debugvar, 0, 1011 CTL_DEBUG, i, CTL_DEBUG_VALUE, CTL_EOL); 1012 sysctl_createv(clog, 0, NULL, NULL, 1013 CTLFLAG_PERMANENT, 1014 CTLTYPE_INT, cdp->debugname, NULL, 1015 NULL, 0, cdp->debugvar, 0, 1016 CTL_DEBUG, CTL_CREATE, CTL_EOL); 1017 } 1018 } 1019 #endif /* DEBUG */ 1020 1021 /* 1022 * ******************************************************************** 1023 * section 2: private node-specific helper routines. 1024 * ******************************************************************** 1025 */ 1026 1027 #ifdef DIAGNOSTIC 1028 static int 1029 sysctl_kern_trigger_panic(SYSCTLFN_ARGS) 1030 { 1031 int newtrig, error; 1032 struct sysctlnode node; 1033 1034 newtrig = 0; 1035 node = *rnode; 1036 node.sysctl_data = &newtrig; 1037 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 1038 if (error || newp == NULL) 1039 return (error); 1040 1041 if (newtrig != 0) 1042 panic("Panic triggered"); 1043 1044 return (error); 1045 } 1046 #endif 1047 1048 /* 1049 * sysctl helper routine for kern.maxvnodes. Drain vnodes if 1050 * new value is lower than desiredvnodes and then calls reinit 1051 * routines that needs to adjust to the new value. 1052 */ 1053 static int 1054 sysctl_kern_maxvnodes(SYSCTLFN_ARGS) 1055 { 1056 int error, new_vnodes, old_vnodes, new_max; 1057 struct sysctlnode node; 1058 1059 new_vnodes = desiredvnodes; 1060 node = *rnode; 1061 node.sysctl_data = &new_vnodes; 1062 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 1063 if (error || newp == NULL) 1064 return (error); 1065 1066 /* Limits: 75% of KVA and physical memory. */ 1067 new_max = calc_cache_size(kernel_map, 75, 75) / VNODE_COST; 1068 if (new_vnodes > new_max) 1069 new_vnodes = new_max; 1070 1071 old_vnodes = desiredvnodes; 1072 desiredvnodes = new_vnodes; 1073 if (new_vnodes < old_vnodes) { 1074 error = vfs_drainvnodes(new_vnodes, l); 1075 if (error) { 1076 desiredvnodes = old_vnodes; 1077 return (error); 1078 } 1079 } 1080 vfs_reinit(); 1081 nchreinit(); 1082 1083 return (0); 1084 } 1085 1086 /* 1087 * sysctl helper routine for rtc_offset - set time after changes 1088 */ 1089 static int 1090 sysctl_kern_rtc_offset(SYSCTLFN_ARGS) 1091 { 1092 struct timespec ts, delta; 1093 int error, new_rtc_offset; 1094 struct sysctlnode node; 1095 1096 new_rtc_offset = rtc_offset; 1097 node = *rnode; 1098 node.sysctl_data = &new_rtc_offset; 1099 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 1100 if (error || newp == NULL) 1101 return (error); 1102 1103 if (kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_TIME, 1104 KAUTH_REQ_SYSTEM_TIME_RTCOFFSET, 1105 KAUTH_ARG(new_rtc_offset), NULL, NULL)) 1106 return (EPERM); 1107 if (rtc_offset == new_rtc_offset) 1108 return (0); 1109 1110 /* if we change the offset, adjust the time */ 1111 nanotime(&ts); 1112 delta.tv_sec = 60 * (new_rtc_offset - rtc_offset); 1113 delta.tv_nsec = 0; 1114 timespecadd(&ts, &delta, &ts); 1115 rtc_offset = new_rtc_offset; 1116 return (settime(l->l_proc, &ts)); 1117 } 1118 1119 /* 1120 * sysctl helper routine for kern.maxproc. Ensures that the new 1121 * values are not too low or too high. 1122 */ 1123 static int 1124 sysctl_kern_maxproc(SYSCTLFN_ARGS) 1125 { 1126 int error, nmaxproc; 1127 struct sysctlnode node; 1128 1129 nmaxproc = maxproc; 1130 node = *rnode; 1131 node.sysctl_data = &nmaxproc; 1132 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 1133 if (error || newp == NULL) 1134 return (error); 1135 1136 if (nmaxproc < 0 || nmaxproc >= PID_MAX) 1137 return (EINVAL); 1138 #ifdef __HAVE_CPU_MAXPROC 1139 if (nmaxproc > cpu_maxproc()) 1140 return (EINVAL); 1141 #endif 1142 maxproc = nmaxproc; 1143 1144 return (0); 1145 } 1146 1147 /* 1148 * sysctl helper function for kern.hostid. The hostid is a long, but 1149 * we export it as an int, so we need to give it a little help. 1150 */ 1151 static int 1152 sysctl_kern_hostid(SYSCTLFN_ARGS) 1153 { 1154 int error, inthostid; 1155 struct sysctlnode node; 1156 1157 inthostid = hostid; /* XXX assumes sizeof int <= sizeof long */ 1158 node = *rnode; 1159 node.sysctl_data = &inthostid; 1160 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 1161 if (error || newp == NULL) 1162 return (error); 1163 1164 hostid = (unsigned)inthostid; 1165 1166 return (0); 1167 } 1168 1169 /* 1170 * sysctl helper function for kern.hostname and kern.domainnname. 1171 * resets the relevant recorded length when the underlying name is 1172 * changed. 1173 */ 1174 static int 1175 sysctl_setlen(SYSCTLFN_ARGS) 1176 { 1177 int error; 1178 1179 error = sysctl_lookup(SYSCTLFN_CALL(rnode)); 1180 if (error || newp == NULL) 1181 return (error); 1182 1183 switch (rnode->sysctl_num) { 1184 case KERN_HOSTNAME: 1185 hostnamelen = strlen((const char*)rnode->sysctl_data); 1186 break; 1187 case KERN_DOMAINNAME: 1188 domainnamelen = strlen((const char*)rnode->sysctl_data); 1189 break; 1190 } 1191 1192 return (0); 1193 } 1194 1195 /* 1196 * sysctl helper routine for kern.clockrate. Assembles a struct on 1197 * the fly to be returned to the caller. 1198 */ 1199 static int 1200 sysctl_kern_clockrate(SYSCTLFN_ARGS) 1201 { 1202 struct clockinfo clkinfo; 1203 struct sysctlnode node; 1204 1205 clkinfo.tick = tick; 1206 clkinfo.tickadj = tickadj; 1207 clkinfo.hz = hz; 1208 clkinfo.profhz = profhz; 1209 clkinfo.stathz = stathz ? stathz : hz; 1210 1211 node = *rnode; 1212 node.sysctl_data = &clkinfo; 1213 return (sysctl_lookup(SYSCTLFN_CALL(&node))); 1214 } 1215 1216 1217 /* 1218 * sysctl helper routine for kern.file pseudo-subtree. 1219 */ 1220 static int 1221 sysctl_kern_file(SYSCTLFN_ARGS) 1222 { 1223 int error; 1224 size_t buflen; 1225 struct file *fp, *dp, *np, fbuf; 1226 char *start, *where; 1227 1228 start = where = oldp; 1229 buflen = *oldlenp; 1230 dp = NULL; 1231 1232 if (where == NULL) { 1233 /* 1234 * overestimate by 10 files 1235 */ 1236 *oldlenp = sizeof(filehead) + (nfiles + 10) * 1237 sizeof(struct file); 1238 return (0); 1239 } 1240 1241 /* 1242 * first dcopyout filehead 1243 */ 1244 if (buflen < sizeof(filehead)) { 1245 *oldlenp = 0; 1246 return (0); 1247 } 1248 sysctl_unlock(); 1249 error = dcopyout(l, &filehead, where, sizeof(filehead)); 1250 if (error) { 1251 sysctl_relock(); 1252 return error; 1253 } 1254 buflen -= sizeof(filehead); 1255 where += sizeof(filehead); 1256 1257 /* 1258 * allocate dummy file descriptor to make position in list 1259 */ 1260 if ((dp = fgetdummy()) == NULL) { 1261 sysctl_relock(); 1262 return ENOMEM; 1263 } 1264 1265 /* 1266 * followed by an array of file structures 1267 */ 1268 mutex_enter(&filelist_lock); 1269 for (fp = LIST_FIRST(&filehead); fp != NULL; fp = np) { 1270 np = LIST_NEXT(fp, f_list); 1271 mutex_enter(&fp->f_lock); 1272 if (fp->f_count == 0) { 1273 mutex_exit(&fp->f_lock); 1274 continue; 1275 } 1276 /* 1277 * XXX Need to prevent that from being an alternative way 1278 * XXX to getting process information. 1279 */ 1280 if (kauth_authorize_generic(l->l_cred, 1281 KAUTH_GENERIC_CANSEE, fp->f_cred) != 0) { 1282 mutex_exit(&fp->f_lock); 1283 continue; 1284 } 1285 if (buflen < sizeof(struct file)) { 1286 *oldlenp = where - start; 1287 mutex_exit(&fp->f_lock); 1288 error = ENOMEM; 1289 break; 1290 } 1291 memcpy(&fbuf, fp, sizeof(fbuf)); 1292 LIST_INSERT_AFTER(fp, dp, f_list); 1293 mutex_exit(&fp->f_lock); 1294 mutex_exit(&filelist_lock); 1295 error = dcopyout(l, &fbuf, where, sizeof(fbuf)); 1296 if (error) { 1297 mutex_enter(&filelist_lock); 1298 LIST_REMOVE(dp, f_list); 1299 break; 1300 } 1301 buflen -= sizeof(struct file); 1302 where += sizeof(struct file); 1303 mutex_enter(&filelist_lock); 1304 np = LIST_NEXT(dp, f_list); 1305 LIST_REMOVE(dp, f_list); 1306 } 1307 mutex_exit(&filelist_lock); 1308 *oldlenp = where - start; 1309 if (dp != NULL) 1310 fputdummy(dp); 1311 sysctl_relock(); 1312 return (error); 1313 } 1314 1315 /* 1316 * sysctl helper routine for kern.msgbufsize and kern.msgbuf. For the 1317 * former it merely checks the message buffer is set up. For the latter, 1318 * it also copies out the data if necessary. 1319 */ 1320 static int 1321 sysctl_msgbuf(SYSCTLFN_ARGS) 1322 { 1323 char *where = oldp; 1324 size_t len, maxlen; 1325 long beg, end; 1326 extern kmutex_t log_lock; 1327 int error; 1328 1329 if (!msgbufenabled || msgbufp->msg_magic != MSG_MAGIC) { 1330 msgbufenabled = 0; 1331 return (ENXIO); 1332 } 1333 1334 switch (rnode->sysctl_num) { 1335 case KERN_MSGBUFSIZE: { 1336 struct sysctlnode node = *rnode; 1337 int msg_bufs = (int)msgbufp->msg_bufs; 1338 node.sysctl_data = &msg_bufs; 1339 return (sysctl_lookup(SYSCTLFN_CALL(&node))); 1340 } 1341 case KERN_MSGBUF: 1342 break; 1343 default: 1344 return (EOPNOTSUPP); 1345 } 1346 1347 if (newp != NULL) 1348 return (EPERM); 1349 1350 if (oldp == NULL) { 1351 /* always return full buffer size */ 1352 *oldlenp = msgbufp->msg_bufs; 1353 return (0); 1354 } 1355 1356 sysctl_unlock(); 1357 1358 /* 1359 * First, copy from the write pointer to the end of 1360 * message buffer. 1361 */ 1362 error = 0; 1363 mutex_spin_enter(&log_lock); 1364 maxlen = MIN(msgbufp->msg_bufs, *oldlenp); 1365 beg = msgbufp->msg_bufx; 1366 end = msgbufp->msg_bufs; 1367 mutex_spin_exit(&log_lock); 1368 1369 while (maxlen > 0) { 1370 len = MIN(end - beg, maxlen); 1371 if (len == 0) 1372 break; 1373 /* XXX unlocked, but hardly matters. */ 1374 error = dcopyout(l, &msgbufp->msg_bufc[beg], where, len); 1375 if (error) 1376 break; 1377 where += len; 1378 maxlen -= len; 1379 1380 /* 1381 * ... then, copy from the beginning of message buffer to 1382 * the write pointer. 1383 */ 1384 beg = 0; 1385 end = msgbufp->msg_bufx; 1386 } 1387 1388 sysctl_relock(); 1389 return (error); 1390 } 1391 1392 /* 1393 * sysctl helper routine for kern.defcorename. In the case of a new 1394 * string being assigned, check that it's not a zero-length string. 1395 * (XXX the check in -current doesn't work, but do we really care?) 1396 */ 1397 static int 1398 sysctl_kern_defcorename(SYSCTLFN_ARGS) 1399 { 1400 int error; 1401 char *newcorename; 1402 struct sysctlnode node; 1403 1404 newcorename = PNBUF_GET(); 1405 node = *rnode; 1406 node.sysctl_data = &newcorename[0]; 1407 memcpy(node.sysctl_data, rnode->sysctl_data, MAXPATHLEN); 1408 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 1409 if (error || newp == NULL) { 1410 goto done; 1411 } 1412 1413 /* 1414 * when sysctl_lookup() deals with a string, it's guaranteed 1415 * to come back nul terminated. So there. :) 1416 */ 1417 if (strlen(newcorename) == 0) { 1418 error = EINVAL; 1419 } else { 1420 memcpy(rnode->sysctl_data, node.sysctl_data, MAXPATHLEN); 1421 error = 0; 1422 } 1423 done: 1424 PNBUF_PUT(newcorename); 1425 return error; 1426 } 1427 1428 /* 1429 * sysctl helper routine for kern.cp_time node. Adds up cpu time 1430 * across all cpus. 1431 */ 1432 static int 1433 sysctl_kern_cptime(SYSCTLFN_ARGS) 1434 { 1435 struct sysctlnode node = *rnode; 1436 uint64_t *cp_time = NULL; 1437 int error, n = ncpu, i; 1438 struct cpu_info *ci; 1439 CPU_INFO_ITERATOR cii; 1440 1441 /* 1442 * if you specifically pass a buffer that is the size of the 1443 * sum, or if you are probing for the size, you get the "sum" 1444 * of cp_time (and the size thereof) across all processors. 1445 * 1446 * alternately, you can pass an additional mib number and get 1447 * cp_time for that particular processor. 1448 */ 1449 switch (namelen) { 1450 case 0: 1451 if (*oldlenp == sizeof(uint64_t) * CPUSTATES || oldp == NULL) { 1452 node.sysctl_size = sizeof(uint64_t) * CPUSTATES; 1453 n = -1; /* SUM */ 1454 } 1455 else { 1456 node.sysctl_size = n * sizeof(uint64_t) * CPUSTATES; 1457 n = -2; /* ALL */ 1458 } 1459 break; 1460 case 1: 1461 if (name[0] < 0 || name[0] >= n) 1462 return (ENOENT); /* ENOSUCHPROCESSOR */ 1463 node.sysctl_size = sizeof(uint64_t) * CPUSTATES; 1464 n = name[0]; 1465 /* 1466 * adjust these so that sysctl_lookup() will be happy 1467 */ 1468 name++; 1469 namelen--; 1470 break; 1471 default: 1472 return (EINVAL); 1473 } 1474 1475 cp_time = kmem_alloc(node.sysctl_size, KM_SLEEP); 1476 if (cp_time == NULL) 1477 return (ENOMEM); 1478 node.sysctl_data = cp_time; 1479 memset(cp_time, 0, node.sysctl_size); 1480 1481 for (CPU_INFO_FOREACH(cii, ci)) { 1482 if (n <= 0) { 1483 for (i = 0; i < CPUSTATES; i++) { 1484 cp_time[i] += ci->ci_schedstate.spc_cp_time[i]; 1485 } 1486 } 1487 /* 1488 * if a specific processor was requested and we just 1489 * did it, we're done here 1490 */ 1491 if (n == 0) 1492 break; 1493 /* 1494 * if doing "all", skip to next cp_time set for next processor 1495 */ 1496 if (n == -2) 1497 cp_time += CPUSTATES; 1498 /* 1499 * if we're doing a specific processor, we're one 1500 * processor closer 1501 */ 1502 if (n > 0) 1503 n--; 1504 } 1505 1506 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 1507 kmem_free(node.sysctl_data, node.sysctl_size); 1508 return (error); 1509 } 1510 1511 #if NPTY > 0 1512 /* 1513 * sysctl helper routine for kern.maxptys. Ensures that any new value 1514 * is acceptable to the pty subsystem. 1515 */ 1516 static int 1517 sysctl_kern_maxptys(SYSCTLFN_ARGS) 1518 { 1519 int pty_maxptys(int, int); /* defined in kern/tty_pty.c */ 1520 int error, xmax; 1521 struct sysctlnode node; 1522 1523 /* get current value of maxptys */ 1524 xmax = pty_maxptys(0, 0); 1525 1526 node = *rnode; 1527 node.sysctl_data = &xmax; 1528 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 1529 if (error || newp == NULL) 1530 return (error); 1531 1532 if (xmax != pty_maxptys(xmax, 1)) 1533 return (EINVAL); 1534 1535 return (0); 1536 } 1537 #endif /* NPTY > 0 */ 1538 1539 /* 1540 * sysctl helper routine for kern.sbmax. Basically just ensures that 1541 * any new value is not too small. 1542 */ 1543 static int 1544 sysctl_kern_sbmax(SYSCTLFN_ARGS) 1545 { 1546 int error, new_sbmax; 1547 struct sysctlnode node; 1548 1549 new_sbmax = sb_max; 1550 node = *rnode; 1551 node.sysctl_data = &new_sbmax; 1552 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 1553 if (error || newp == NULL) 1554 return (error); 1555 1556 KERNEL_LOCK(1, NULL); 1557 error = sb_max_set(new_sbmax); 1558 KERNEL_UNLOCK_ONE(NULL); 1559 1560 return (error); 1561 } 1562 1563 /* 1564 * sysctl helper routine for kern.urandom node. Picks a random number 1565 * for you. 1566 */ 1567 static int 1568 sysctl_kern_urnd(SYSCTLFN_ARGS) 1569 { 1570 #if NRND > 0 1571 int v, rv; 1572 1573 KERNEL_LOCK(1, NULL); 1574 rv = rnd_extract_data(&v, sizeof(v), RND_EXTRACT_ANY); 1575 KERNEL_UNLOCK_ONE(NULL); 1576 if (rv == sizeof(v)) { 1577 struct sysctlnode node = *rnode; 1578 node.sysctl_data = &v; 1579 return (sysctl_lookup(SYSCTLFN_CALL(&node))); 1580 } 1581 else 1582 return (EIO); /*XXX*/ 1583 #else 1584 return (EOPNOTSUPP); 1585 #endif 1586 } 1587 1588 /* 1589 * sysctl helper routine for kern.arandom node. Picks a random number 1590 * for you. 1591 */ 1592 static int 1593 sysctl_kern_arnd(SYSCTLFN_ARGS) 1594 { 1595 #if NRND > 0 1596 int error; 1597 void *v; 1598 struct sysctlnode node = *rnode; 1599 1600 if (*oldlenp == 0) 1601 return 0; 1602 if (*oldlenp > 8192) 1603 return E2BIG; 1604 1605 v = kmem_alloc(*oldlenp, KM_SLEEP); 1606 arc4randbytes(v, *oldlenp); 1607 node.sysctl_data = v; 1608 node.sysctl_size = *oldlenp; 1609 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 1610 kmem_free(v, *oldlenp); 1611 return error; 1612 #else 1613 return (EOPNOTSUPP); 1614 #endif 1615 } 1616 /* 1617 * sysctl helper routine to do kern.lwp.* work. 1618 */ 1619 static int 1620 sysctl_kern_lwp(SYSCTLFN_ARGS) 1621 { 1622 struct kinfo_lwp klwp; 1623 struct proc *p; 1624 struct lwp *l2, *l3; 1625 char *where, *dp; 1626 int pid, elem_size, elem_count; 1627 int buflen, needed, error; 1628 bool gotit; 1629 1630 if (namelen == 1 && name[0] == CTL_QUERY) 1631 return (sysctl_query(SYSCTLFN_CALL(rnode))); 1632 1633 dp = where = oldp; 1634 buflen = where != NULL ? *oldlenp : 0; 1635 error = needed = 0; 1636 1637 if (newp != NULL || namelen != 3) 1638 return (EINVAL); 1639 pid = name[0]; 1640 elem_size = name[1]; 1641 elem_count = name[2]; 1642 1643 sysctl_unlock(); 1644 if (pid == -1) { 1645 mutex_enter(proc_lock); 1646 PROCLIST_FOREACH(p, &allproc) { 1647 /* Grab a hold on the process. */ 1648 if (!rw_tryenter(&p->p_reflock, RW_READER)) { 1649 continue; 1650 } 1651 mutex_exit(proc_lock); 1652 1653 mutex_enter(p->p_lock); 1654 LIST_FOREACH(l2, &p->p_lwps, l_sibling) { 1655 if (buflen >= elem_size && elem_count > 0) { 1656 lwp_lock(l2); 1657 fill_lwp(l2, &klwp); 1658 lwp_unlock(l2); 1659 mutex_exit(p->p_lock); 1660 1661 /* 1662 * Copy out elem_size, but not 1663 * larger than the size of a 1664 * struct kinfo_proc2. 1665 */ 1666 error = dcopyout(l, &klwp, dp, 1667 min(sizeof(klwp), elem_size)); 1668 if (error) { 1669 rw_exit(&p->p_reflock); 1670 goto cleanup; 1671 } 1672 mutex_enter(p->p_lock); 1673 LIST_FOREACH(l3, &p->p_lwps, 1674 l_sibling) { 1675 if (l2 == l3) 1676 break; 1677 } 1678 if (l3 == NULL) { 1679 mutex_exit(p->p_lock); 1680 rw_exit(&p->p_reflock); 1681 error = EAGAIN; 1682 goto cleanup; 1683 } 1684 dp += elem_size; 1685 buflen -= elem_size; 1686 elem_count--; 1687 } 1688 needed += elem_size; 1689 } 1690 mutex_exit(p->p_lock); 1691 1692 /* Drop reference to process. */ 1693 mutex_enter(proc_lock); 1694 rw_exit(&p->p_reflock); 1695 } 1696 mutex_exit(proc_lock); 1697 } else { 1698 mutex_enter(proc_lock); 1699 p = p_find(pid, PFIND_LOCKED); 1700 if (p == NULL) { 1701 error = ESRCH; 1702 mutex_exit(proc_lock); 1703 goto cleanup; 1704 } 1705 /* Grab a hold on the process. */ 1706 gotit = rw_tryenter(&p->p_reflock, RW_READER); 1707 mutex_exit(proc_lock); 1708 if (!gotit) { 1709 error = ESRCH; 1710 goto cleanup; 1711 } 1712 1713 mutex_enter(p->p_lock); 1714 LIST_FOREACH(l2, &p->p_lwps, l_sibling) { 1715 if (buflen >= elem_size && elem_count > 0) { 1716 lwp_lock(l2); 1717 fill_lwp(l2, &klwp); 1718 lwp_unlock(l2); 1719 mutex_exit(p->p_lock); 1720 /* 1721 * Copy out elem_size, but not larger than 1722 * the size of a struct kinfo_proc2. 1723 */ 1724 error = dcopyout(l, &klwp, dp, 1725 min(sizeof(klwp), elem_size)); 1726 if (error) { 1727 rw_exit(&p->p_reflock); 1728 goto cleanup; 1729 } 1730 mutex_enter(p->p_lock); 1731 LIST_FOREACH(l3, &p->p_lwps, l_sibling) { 1732 if (l2 == l3) 1733 break; 1734 } 1735 if (l3 == NULL) { 1736 mutex_exit(p->p_lock); 1737 rw_exit(&p->p_reflock); 1738 error = EAGAIN; 1739 goto cleanup; 1740 } 1741 dp += elem_size; 1742 buflen -= elem_size; 1743 elem_count--; 1744 } 1745 needed += elem_size; 1746 } 1747 mutex_exit(p->p_lock); 1748 1749 /* Drop reference to process. */ 1750 rw_exit(&p->p_reflock); 1751 } 1752 1753 if (where != NULL) { 1754 *oldlenp = dp - where; 1755 if (needed > *oldlenp) { 1756 sysctl_relock(); 1757 return (ENOMEM); 1758 } 1759 } else { 1760 needed += KERN_LWPSLOP; 1761 *oldlenp = needed; 1762 } 1763 error = 0; 1764 cleanup: 1765 sysctl_relock(); 1766 return (error); 1767 } 1768 1769 /* 1770 * sysctl helper routine for kern.forkfsleep node. Ensures that the 1771 * given value is not too large or two small, and is at least one 1772 * timer tick if not zero. 1773 */ 1774 static int 1775 sysctl_kern_forkfsleep(SYSCTLFN_ARGS) 1776 { 1777 /* userland sees value in ms, internally is in ticks */ 1778 extern int forkfsleep; /* defined in kern/kern_fork.c */ 1779 int error, timo, lsleep; 1780 struct sysctlnode node; 1781 1782 lsleep = forkfsleep * 1000 / hz; 1783 node = *rnode; 1784 node.sysctl_data = &lsleep; 1785 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 1786 if (error || newp == NULL) 1787 return (error); 1788 1789 /* refuse negative values, and overly 'long time' */ 1790 if (lsleep < 0 || lsleep > MAXSLP * 1000) 1791 return (EINVAL); 1792 1793 timo = mstohz(lsleep); 1794 1795 /* if the interval is >0 ms && <1 tick, use 1 tick */ 1796 if (lsleep != 0 && timo == 0) 1797 forkfsleep = 1; 1798 else 1799 forkfsleep = timo; 1800 1801 return (0); 1802 } 1803 1804 /* 1805 * sysctl helper routine for kern.root_partition 1806 */ 1807 static int 1808 sysctl_kern_root_partition(SYSCTLFN_ARGS) 1809 { 1810 int rootpart = DISKPART(rootdev); 1811 struct sysctlnode node = *rnode; 1812 1813 node.sysctl_data = &rootpart; 1814 return (sysctl_lookup(SYSCTLFN_CALL(&node))); 1815 } 1816 1817 /* 1818 * sysctl helper function for kern.drivers 1819 */ 1820 static int 1821 sysctl_kern_drivers(SYSCTLFN_ARGS) 1822 { 1823 int error; 1824 size_t buflen; 1825 struct kinfo_drivers kd; 1826 char *start, *where; 1827 const char *dname; 1828 int i; 1829 extern struct devsw_conv *devsw_conv; 1830 extern int max_devsw_convs; 1831 1832 if (newp != NULL || namelen != 0) 1833 return (EINVAL); 1834 1835 start = where = oldp; 1836 buflen = *oldlenp; 1837 if (where == NULL) { 1838 *oldlenp = max_devsw_convs * sizeof kd; 1839 return 0; 1840 } 1841 1842 /* 1843 * An array of kinfo_drivers structures 1844 */ 1845 error = 0; 1846 sysctl_unlock(); 1847 mutex_enter(&device_lock); 1848 for (i = 0; i < max_devsw_convs; i++) { 1849 dname = devsw_conv[i].d_name; 1850 if (dname == NULL) 1851 continue; 1852 if (buflen < sizeof kd) { 1853 error = ENOMEM; 1854 break; 1855 } 1856 memset(&kd, 0, sizeof(kd)); 1857 kd.d_bmajor = devsw_conv[i].d_bmajor; 1858 kd.d_cmajor = devsw_conv[i].d_cmajor; 1859 strlcpy(kd.d_name, dname, sizeof kd.d_name); 1860 mutex_exit(&device_lock); 1861 error = dcopyout(l, &kd, where, sizeof kd); 1862 mutex_enter(&device_lock); 1863 if (error != 0) 1864 break; 1865 buflen -= sizeof kd; 1866 where += sizeof kd; 1867 } 1868 mutex_exit(&device_lock); 1869 sysctl_relock(); 1870 *oldlenp = where - start; 1871 return error; 1872 } 1873 1874 /* 1875 * sysctl helper function for kern.file2 1876 */ 1877 static int 1878 sysctl_kern_file2(SYSCTLFN_ARGS) 1879 { 1880 struct proc *p; 1881 struct file *fp, *tp, *np; 1882 struct filedesc *fd; 1883 struct kinfo_file kf; 1884 char *dp; 1885 u_int i, op; 1886 size_t len, needed, elem_size, out_size; 1887 int error, arg, elem_count; 1888 fdfile_t *ff; 1889 fdtab_t *dt; 1890 1891 if (namelen == 1 && name[0] == CTL_QUERY) 1892 return (sysctl_query(SYSCTLFN_CALL(rnode))); 1893 1894 if (namelen != 4) 1895 return (EINVAL); 1896 1897 error = 0; 1898 dp = oldp; 1899 len = (oldp != NULL) ? *oldlenp : 0; 1900 op = name[0]; 1901 arg = name[1]; 1902 elem_size = name[2]; 1903 elem_count = name[3]; 1904 out_size = MIN(sizeof(kf), elem_size); 1905 needed = 0; 1906 1907 if (elem_size < 1 || elem_count < 0) 1908 return (EINVAL); 1909 1910 switch (op) { 1911 case KERN_FILE_BYFILE: 1912 /* 1913 * doesn't use arg so it must be zero 1914 */ 1915 if (arg != 0) 1916 return (EINVAL); 1917 sysctl_unlock(); 1918 /* 1919 * allocate dummy file descriptor to make position in list 1920 */ 1921 if ((tp = fgetdummy()) == NULL) { 1922 sysctl_relock(); 1923 return ENOMEM; 1924 } 1925 mutex_enter(&filelist_lock); 1926 for (fp = LIST_FIRST(&filehead); fp != NULL; fp = np) { 1927 np = LIST_NEXT(fp, f_list); 1928 mutex_enter(&fp->f_lock); 1929 if (fp->f_count == 0) { 1930 mutex_exit(&fp->f_lock); 1931 continue; 1932 } 1933 /* 1934 * XXX Need to prevent that from being an alternative 1935 * XXX way for getting process information. 1936 */ 1937 if (kauth_authorize_generic(l->l_cred, 1938 KAUTH_GENERIC_CANSEE, fp->f_cred) != 0) { 1939 mutex_exit(&fp->f_lock); 1940 continue; 1941 } 1942 if (len >= elem_size && elem_count > 0) { 1943 fill_file(&kf, fp, NULL, 0, 0); 1944 LIST_INSERT_AFTER(fp, tp, f_list); 1945 mutex_exit(&fp->f_lock); 1946 mutex_exit(&filelist_lock); 1947 error = dcopyout(l, &kf, dp, out_size); 1948 mutex_enter(&filelist_lock); 1949 np = LIST_NEXT(tp, f_list); 1950 LIST_REMOVE(tp, f_list); 1951 if (error) { 1952 break; 1953 } 1954 dp += elem_size; 1955 len -= elem_size; 1956 } else { 1957 mutex_exit(&fp->f_lock); 1958 } 1959 needed += elem_size; 1960 if (elem_count > 0 && elem_count != INT_MAX) 1961 elem_count--; 1962 } 1963 mutex_exit(&filelist_lock); 1964 fputdummy(tp); 1965 sysctl_relock(); 1966 break; 1967 case KERN_FILE_BYPID: 1968 if (arg < -1) 1969 /* -1 means all processes */ 1970 return (EINVAL); 1971 sysctl_unlock(); 1972 mutex_enter(proc_lock); 1973 PROCLIST_FOREACH(p, &allproc) { 1974 if (p->p_stat == SIDL) { 1975 /* skip embryonic processes */ 1976 continue; 1977 } 1978 if (arg > 0 && p->p_pid != arg) { 1979 /* pick only the one we want */ 1980 /* XXX want 0 to mean "kernel files" */ 1981 continue; 1982 } 1983 mutex_enter(p->p_lock); 1984 error = kauth_authorize_process(l->l_cred, 1985 KAUTH_PROCESS_CANSEE, p, 1986 KAUTH_ARG(KAUTH_REQ_PROCESS_CANSEE_OPENFILES), 1987 NULL, NULL); 1988 mutex_exit(p->p_lock); 1989 if (error != 0) { 1990 /* 1991 * Don't leak kauth retval if we're silently 1992 * skipping this entry. 1993 */ 1994 error = 0; 1995 continue; 1996 } 1997 1998 /* 1999 * Grab a hold on the process. 2000 */ 2001 if (!rw_tryenter(&p->p_reflock, RW_READER)) { 2002 continue; 2003 } 2004 mutex_exit(proc_lock); 2005 2006 /* XXX Do we need to check permission per file? */ 2007 fd = p->p_fd; 2008 mutex_enter(&fd->fd_lock); 2009 dt = fd->fd_dt; 2010 for (i = 0; i < dt->dt_nfiles; i++) { 2011 if ((ff = dt->dt_ff[i]) == NULL) { 2012 continue; 2013 } 2014 if ((fp = ff->ff_file) == NULL) { 2015 continue; 2016 } 2017 if (len >= elem_size && elem_count > 0) { 2018 mutex_enter(&fp->f_lock); 2019 fill_file(&kf, fp, ff, i, p->p_pid); 2020 mutex_exit(&fp->f_lock); 2021 mutex_exit(&fd->fd_lock); 2022 error = dcopyout(l, &kf, dp, out_size); 2023 mutex_enter(&fd->fd_lock); 2024 if (error) 2025 break; 2026 dp += elem_size; 2027 len -= elem_size; 2028 } 2029 needed += elem_size; 2030 if (elem_count > 0 && elem_count != INT_MAX) 2031 elem_count--; 2032 } 2033 mutex_exit(&fd->fd_lock); 2034 2035 /* 2036 * Release reference to process. 2037 */ 2038 mutex_enter(proc_lock); 2039 rw_exit(&p->p_reflock); 2040 } 2041 mutex_exit(proc_lock); 2042 sysctl_relock(); 2043 break; 2044 default: 2045 return (EINVAL); 2046 } 2047 2048 if (oldp == NULL) 2049 needed += KERN_FILESLOP * elem_size; 2050 *oldlenp = needed; 2051 2052 return (error); 2053 } 2054 2055 static void 2056 fill_file(struct kinfo_file *kp, const file_t *fp, const fdfile_t *ff, 2057 int i, pid_t pid) 2058 { 2059 2060 memset(kp, 0, sizeof(*kp)); 2061 2062 kp->ki_fileaddr = PTRTOUINT64(fp); 2063 kp->ki_flag = fp->f_flag; 2064 kp->ki_iflags = 0; 2065 kp->ki_ftype = fp->f_type; 2066 kp->ki_count = fp->f_count; 2067 kp->ki_msgcount = fp->f_msgcount; 2068 kp->ki_fucred = PTRTOUINT64(fp->f_cred); 2069 kp->ki_fuid = kauth_cred_geteuid(fp->f_cred); 2070 kp->ki_fgid = kauth_cred_getegid(fp->f_cred); 2071 kp->ki_fops = PTRTOUINT64(fp->f_ops); 2072 kp->ki_foffset = fp->f_offset; 2073 kp->ki_fdata = PTRTOUINT64(fp->f_data); 2074 2075 /* vnode information to glue this file to something */ 2076 if (fp->f_type == DTYPE_VNODE) { 2077 struct vnode *vp = (struct vnode *)fp->f_data; 2078 2079 kp->ki_vun = PTRTOUINT64(vp->v_un.vu_socket); 2080 kp->ki_vsize = vp->v_size; 2081 kp->ki_vtype = vp->v_type; 2082 kp->ki_vtag = vp->v_tag; 2083 kp->ki_vdata = PTRTOUINT64(vp->v_data); 2084 } 2085 2086 /* process information when retrieved via KERN_FILE_BYPID */ 2087 if (ff != NULL) { 2088 kp->ki_pid = pid; 2089 kp->ki_fd = i; 2090 kp->ki_ofileflags = ff->ff_exclose; 2091 kp->ki_usecount = ff->ff_refcnt; 2092 } 2093 } 2094 2095 static int 2096 sysctl_doeproc(SYSCTLFN_ARGS) 2097 { 2098 union { 2099 struct kinfo_proc kproc; 2100 struct kinfo_proc2 kproc2; 2101 } *kbuf; 2102 struct proc *p, *next, *marker; 2103 char *where, *dp; 2104 int type, op, arg, error; 2105 u_int elem_size, kelem_size, elem_count; 2106 size_t buflen, needed; 2107 bool match, zombie, mmmbrains; 2108 2109 if (namelen == 1 && name[0] == CTL_QUERY) 2110 return (sysctl_query(SYSCTLFN_CALL(rnode))); 2111 2112 dp = where = oldp; 2113 buflen = where != NULL ? *oldlenp : 0; 2114 error = 0; 2115 needed = 0; 2116 type = rnode->sysctl_num; 2117 2118 if (type == KERN_PROC) { 2119 if (namelen != 2 && !(namelen == 1 && name[0] == KERN_PROC_ALL)) 2120 return (EINVAL); 2121 op = name[0]; 2122 if (op != KERN_PROC_ALL) 2123 arg = name[1]; 2124 else 2125 arg = 0; /* Quell compiler warning */ 2126 elem_count = 0; /* Ditto */ 2127 kelem_size = elem_size = sizeof(kbuf->kproc); 2128 } else { 2129 if (namelen != 4) 2130 return (EINVAL); 2131 op = name[0]; 2132 arg = name[1]; 2133 elem_size = name[2]; 2134 elem_count = name[3]; 2135 kelem_size = sizeof(kbuf->kproc2); 2136 } 2137 2138 sysctl_unlock(); 2139 2140 kbuf = kmem_alloc(sizeof(*kbuf), KM_SLEEP); 2141 marker = kmem_alloc(sizeof(*marker), KM_SLEEP); 2142 marker->p_flag = PK_MARKER; 2143 2144 mutex_enter(proc_lock); 2145 mmmbrains = false; 2146 for (p = LIST_FIRST(&allproc);; p = next) { 2147 if (p == NULL) { 2148 if (!mmmbrains) { 2149 p = LIST_FIRST(&zombproc); 2150 mmmbrains = true; 2151 } 2152 if (p == NULL) 2153 break; 2154 } 2155 next = LIST_NEXT(p, p_list); 2156 if ((p->p_flag & PK_MARKER) != 0) 2157 continue; 2158 2159 /* 2160 * Skip embryonic processes. 2161 */ 2162 if (p->p_stat == SIDL) 2163 continue; 2164 2165 mutex_enter(p->p_lock); 2166 error = kauth_authorize_process(l->l_cred, 2167 KAUTH_PROCESS_CANSEE, p, 2168 KAUTH_ARG(KAUTH_REQ_PROCESS_CANSEE_ENTRY), NULL, NULL); 2169 if (error != 0) { 2170 mutex_exit(p->p_lock); 2171 continue; 2172 } 2173 2174 /* 2175 * TODO - make more efficient (see notes below). 2176 * do by session. 2177 */ 2178 switch (op) { 2179 case KERN_PROC_PID: 2180 /* could do this with just a lookup */ 2181 match = (p->p_pid == (pid_t)arg); 2182 break; 2183 2184 case KERN_PROC_PGRP: 2185 /* could do this by traversing pgrp */ 2186 match = (p->p_pgrp->pg_id == (pid_t)arg); 2187 break; 2188 2189 case KERN_PROC_SESSION: 2190 match = (p->p_session->s_sid == (pid_t)arg); 2191 break; 2192 2193 case KERN_PROC_TTY: 2194 match = true; 2195 if (arg == (int) KERN_PROC_TTY_REVOKE) { 2196 if ((p->p_lflag & PL_CONTROLT) == 0 || 2197 p->p_session->s_ttyp == NULL || 2198 p->p_session->s_ttyvp != NULL) { 2199 match = false; 2200 } 2201 } else if ((p->p_lflag & PL_CONTROLT) == 0 || 2202 p->p_session->s_ttyp == NULL) { 2203 if ((dev_t)arg != KERN_PROC_TTY_NODEV) { 2204 match = false; 2205 } 2206 } else if (p->p_session->s_ttyp->t_dev != (dev_t)arg) { 2207 match = false; 2208 } 2209 break; 2210 2211 case KERN_PROC_UID: 2212 match = (kauth_cred_geteuid(p->p_cred) == (uid_t)arg); 2213 break; 2214 2215 case KERN_PROC_RUID: 2216 match = (kauth_cred_getuid(p->p_cred) == (uid_t)arg); 2217 break; 2218 2219 case KERN_PROC_GID: 2220 match = (kauth_cred_getegid(p->p_cred) == (uid_t)arg); 2221 break; 2222 2223 case KERN_PROC_RGID: 2224 match = (kauth_cred_getgid(p->p_cred) == (uid_t)arg); 2225 break; 2226 2227 case KERN_PROC_ALL: 2228 match = true; 2229 /* allow everything */ 2230 break; 2231 2232 default: 2233 error = EINVAL; 2234 mutex_exit(p->p_lock); 2235 goto cleanup; 2236 } 2237 if (!match) { 2238 mutex_exit(p->p_lock); 2239 continue; 2240 } 2241 2242 /* 2243 * Grab a hold on the process. 2244 */ 2245 if (mmmbrains) { 2246 zombie = true; 2247 } else { 2248 zombie = !rw_tryenter(&p->p_reflock, RW_READER); 2249 } 2250 if (zombie) { 2251 LIST_INSERT_AFTER(p, marker, p_list); 2252 } 2253 2254 if (buflen >= elem_size && 2255 (type == KERN_PROC || elem_count > 0)) { 2256 if (type == KERN_PROC) { 2257 kbuf->kproc.kp_proc = *p; 2258 fill_eproc(p, &kbuf->kproc.kp_eproc, zombie); 2259 } else { 2260 fill_kproc2(p, &kbuf->kproc2, zombie); 2261 elem_count--; 2262 } 2263 mutex_exit(p->p_lock); 2264 mutex_exit(proc_lock); 2265 /* 2266 * Copy out elem_size, but not larger than kelem_size 2267 */ 2268 error = dcopyout(l, kbuf, dp, 2269 min(kelem_size, elem_size)); 2270 mutex_enter(proc_lock); 2271 if (error) { 2272 goto bah; 2273 } 2274 dp += elem_size; 2275 buflen -= elem_size; 2276 } else { 2277 mutex_exit(p->p_lock); 2278 } 2279 needed += elem_size; 2280 2281 /* 2282 * Release reference to process. 2283 */ 2284 if (zombie) { 2285 next = LIST_NEXT(marker, p_list); 2286 LIST_REMOVE(marker, p_list); 2287 } else { 2288 rw_exit(&p->p_reflock); 2289 } 2290 } 2291 mutex_exit(proc_lock); 2292 2293 if (where != NULL) { 2294 *oldlenp = dp - where; 2295 if (needed > *oldlenp) { 2296 error = ENOMEM; 2297 goto out; 2298 } 2299 } else { 2300 needed += KERN_PROCSLOP; 2301 *oldlenp = needed; 2302 } 2303 if (kbuf) 2304 kmem_free(kbuf, sizeof(*kbuf)); 2305 if (marker) 2306 kmem_free(marker, sizeof(*marker)); 2307 sysctl_relock(); 2308 return 0; 2309 bah: 2310 if (zombie) 2311 LIST_REMOVE(marker, p_list); 2312 else 2313 rw_exit(&p->p_reflock); 2314 cleanup: 2315 mutex_exit(proc_lock); 2316 out: 2317 if (kbuf) 2318 kmem_free(kbuf, sizeof(*kbuf)); 2319 if (marker) 2320 kmem_free(marker, sizeof(*marker)); 2321 sysctl_relock(); 2322 return error; 2323 } 2324 2325 /* 2326 * sysctl helper routine for kern.proc_args pseudo-subtree. 2327 */ 2328 static int 2329 sysctl_kern_proc_args(SYSCTLFN_ARGS) 2330 { 2331 struct ps_strings pss; 2332 struct proc *p; 2333 size_t len, i; 2334 struct uio auio; 2335 struct iovec aiov; 2336 pid_t pid; 2337 int nargv, type, error, argvlen; 2338 char *arg; 2339 char **argv = NULL; 2340 char *tmp; 2341 struct vmspace *vmspace; 2342 vaddr_t psstr_addr; 2343 vaddr_t offsetn; 2344 vaddr_t offsetv; 2345 2346 if (namelen == 1 && name[0] == CTL_QUERY) 2347 return (sysctl_query(SYSCTLFN_CALL(rnode))); 2348 2349 if (newp != NULL || namelen != 2) 2350 return (EINVAL); 2351 pid = name[0]; 2352 type = name[1]; 2353 argv = NULL; 2354 argvlen = 0; 2355 2356 switch (type) { 2357 case KERN_PROC_ARGV: 2358 case KERN_PROC_NARGV: 2359 case KERN_PROC_ENV: 2360 case KERN_PROC_NENV: 2361 /* ok */ 2362 break; 2363 default: 2364 return (EINVAL); 2365 } 2366 2367 sysctl_unlock(); 2368 2369 /* check pid */ 2370 mutex_enter(proc_lock); 2371 if ((p = p_find(pid, PFIND_LOCKED)) == NULL) { 2372 error = EINVAL; 2373 goto out_locked; 2374 } 2375 mutex_enter(p->p_lock); 2376 2377 /* Check permission. */ 2378 if (type == KERN_PROC_ARGV || type == KERN_PROC_NARGV) 2379 error = kauth_authorize_process(l->l_cred, KAUTH_PROCESS_CANSEE, 2380 p, KAUTH_ARG(KAUTH_REQ_PROCESS_CANSEE_ARGS), NULL, NULL); 2381 else if (type == KERN_PROC_ENV || type == KERN_PROC_NENV) 2382 error = kauth_authorize_process(l->l_cred, KAUTH_PROCESS_CANSEE, 2383 p, KAUTH_ARG(KAUTH_REQ_PROCESS_CANSEE_ENV), NULL, NULL); 2384 else 2385 error = EINVAL; /* XXXGCC */ 2386 if (error) { 2387 mutex_exit(p->p_lock); 2388 goto out_locked; 2389 } 2390 2391 if (oldp == NULL) { 2392 if (type == KERN_PROC_NARGV || type == KERN_PROC_NENV) 2393 *oldlenp = sizeof (int); 2394 else 2395 *oldlenp = ARG_MAX; /* XXX XXX XXX */ 2396 error = 0; 2397 mutex_exit(p->p_lock); 2398 goto out_locked; 2399 } 2400 2401 /* 2402 * Zombies don't have a stack, so we can't read their psstrings. 2403 * System processes also don't have a user stack. 2404 */ 2405 if (P_ZOMBIE(p) || (p->p_flag & PK_SYSTEM) != 0) { 2406 error = EINVAL; 2407 mutex_exit(p->p_lock); 2408 goto out_locked; 2409 } 2410 2411 /* 2412 * Lock the process down in memory. 2413 */ 2414 psstr_addr = (vaddr_t)p->p_psstr; 2415 if (type == KERN_PROC_ARGV || type == KERN_PROC_NARGV) { 2416 offsetn = p->p_psnargv; 2417 offsetv = p->p_psargv; 2418 } else { 2419 offsetn = p->p_psnenv; 2420 offsetv = p->p_psenv; 2421 } 2422 vmspace = p->p_vmspace; 2423 uvmspace_addref(vmspace); 2424 mutex_exit(p->p_lock); 2425 mutex_exit(proc_lock); 2426 2427 /* 2428 * Allocate a temporary buffer to hold the arguments. 2429 */ 2430 arg = kmem_alloc(PAGE_SIZE, KM_SLEEP); 2431 2432 /* 2433 * Read in the ps_strings structure. 2434 */ 2435 aiov.iov_base = &pss; 2436 aiov.iov_len = sizeof(pss); 2437 auio.uio_iov = &aiov; 2438 auio.uio_iovcnt = 1; 2439 auio.uio_offset = psstr_addr; 2440 auio.uio_resid = sizeof(pss); 2441 auio.uio_rw = UIO_READ; 2442 UIO_SETUP_SYSSPACE(&auio); 2443 error = uvm_io(&vmspace->vm_map, &auio); 2444 if (error) 2445 goto done; 2446 2447 memcpy(&nargv, (char *)&pss + offsetn, sizeof(nargv)); 2448 if (type == KERN_PROC_NARGV || type == KERN_PROC_NENV) { 2449 error = dcopyout(l, &nargv, oldp, sizeof(nargv)); 2450 *oldlenp = sizeof(nargv); 2451 goto done; 2452 } 2453 /* 2454 * Now read the address of the argument vector. 2455 */ 2456 switch (type) { 2457 case KERN_PROC_ARGV: 2458 /* FALLTHROUGH */ 2459 case KERN_PROC_ENV: 2460 memcpy(&tmp, (char *)&pss + offsetv, sizeof(tmp)); 2461 break; 2462 default: 2463 error = EINVAL; 2464 goto done; 2465 } 2466 2467 #ifdef COMPAT_NETBSD32 2468 if (p->p_flag & PK_32) 2469 len = sizeof(netbsd32_charp) * nargv; 2470 else 2471 #endif 2472 len = sizeof(char *) * nargv; 2473 2474 if ((argvlen = len) != 0) 2475 argv = kmem_alloc(len, KM_SLEEP); 2476 2477 aiov.iov_base = argv; 2478 aiov.iov_len = len; 2479 auio.uio_iov = &aiov; 2480 auio.uio_iovcnt = 1; 2481 auio.uio_offset = (off_t)(unsigned long)tmp; 2482 auio.uio_resid = len; 2483 auio.uio_rw = UIO_READ; 2484 UIO_SETUP_SYSSPACE(&auio); 2485 error = uvm_io(&vmspace->vm_map, &auio); 2486 if (error) 2487 goto done; 2488 2489 /* 2490 * Now copy each string. 2491 */ 2492 len = 0; /* bytes written to user buffer */ 2493 for (i = 0; i < nargv; i++) { 2494 int finished = 0; 2495 vaddr_t base; 2496 size_t xlen; 2497 int j; 2498 2499 #ifdef COMPAT_NETBSD32 2500 if (p->p_flag & PK_32) { 2501 netbsd32_charp *argv32; 2502 2503 argv32 = (netbsd32_charp *)argv; 2504 base = (vaddr_t)NETBSD32PTR64(argv32[i]); 2505 } else 2506 #endif 2507 base = (vaddr_t)argv[i]; 2508 2509 /* 2510 * The program has messed around with its arguments, 2511 * possibly deleting some, and replacing them with 2512 * NULL's. Treat this as the last argument and not 2513 * a failure. 2514 */ 2515 if (base == 0) 2516 break; 2517 2518 while (!finished) { 2519 xlen = PAGE_SIZE - (base & PAGE_MASK); 2520 2521 aiov.iov_base = arg; 2522 aiov.iov_len = PAGE_SIZE; 2523 auio.uio_iov = &aiov; 2524 auio.uio_iovcnt = 1; 2525 auio.uio_offset = base; 2526 auio.uio_resid = xlen; 2527 auio.uio_rw = UIO_READ; 2528 UIO_SETUP_SYSSPACE(&auio); 2529 error = uvm_io(&vmspace->vm_map, &auio); 2530 if (error) 2531 goto done; 2532 2533 /* Look for the end of the string */ 2534 for (j = 0; j < xlen; j++) { 2535 if (arg[j] == '\0') { 2536 xlen = j + 1; 2537 finished = 1; 2538 break; 2539 } 2540 } 2541 2542 /* Check for user buffer overflow */ 2543 if (len + xlen > *oldlenp) { 2544 finished = 1; 2545 if (len > *oldlenp) 2546 xlen = 0; 2547 else 2548 xlen = *oldlenp - len; 2549 } 2550 2551 /* Copyout the page */ 2552 error = dcopyout(l, arg, (char *)oldp + len, xlen); 2553 if (error) 2554 goto done; 2555 2556 len += xlen; 2557 base += xlen; 2558 } 2559 } 2560 *oldlenp = len; 2561 2562 done: 2563 if (argvlen != 0) 2564 kmem_free(argv, argvlen); 2565 uvmspace_free(vmspace); 2566 kmem_free(arg, PAGE_SIZE); 2567 sysctl_relock(); 2568 return error; 2569 2570 out_locked: 2571 mutex_exit(proc_lock); 2572 sysctl_relock(); 2573 return error; 2574 } 2575 2576 static int 2577 sysctl_security_setidcore(SYSCTLFN_ARGS) 2578 { 2579 int newsize, error; 2580 struct sysctlnode node; 2581 2582 node = *rnode; 2583 node.sysctl_data = &newsize; 2584 newsize = *(int *)rnode->sysctl_data; 2585 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 2586 if (error || newp == NULL) 2587 return error; 2588 2589 if (kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_SETIDCORE, 2590 0, NULL, NULL, NULL)) 2591 return (EPERM); 2592 2593 *(int *)rnode->sysctl_data = newsize; 2594 2595 return 0; 2596 } 2597 2598 static int 2599 sysctl_security_setidcorename(SYSCTLFN_ARGS) 2600 { 2601 int error; 2602 char *newsetidcorename; 2603 struct sysctlnode node; 2604 2605 newsetidcorename = PNBUF_GET(); 2606 node = *rnode; 2607 node.sysctl_data = newsetidcorename; 2608 memcpy(node.sysctl_data, rnode->sysctl_data, MAXPATHLEN); 2609 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 2610 if (error || newp == NULL) { 2611 goto out; 2612 } 2613 if (kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_SETIDCORE, 2614 0, NULL, NULL, NULL)) { 2615 error = EPERM; 2616 goto out; 2617 } 2618 if (strlen(newsetidcorename) == 0) { 2619 error = EINVAL; 2620 goto out; 2621 } 2622 memcpy(rnode->sysctl_data, node.sysctl_data, MAXPATHLEN); 2623 out: 2624 PNBUF_PUT(newsetidcorename); 2625 return error; 2626 } 2627 2628 /* 2629 * sysctl helper routine for kern.cp_id node. Maps cpus to their 2630 * cpuids. 2631 */ 2632 static int 2633 sysctl_kern_cpid(SYSCTLFN_ARGS) 2634 { 2635 struct sysctlnode node = *rnode; 2636 uint64_t *cp_id = NULL; 2637 int error, n = ncpu; 2638 struct cpu_info *ci; 2639 CPU_INFO_ITERATOR cii; 2640 2641 /* 2642 * Here you may either retrieve a single cpu id or the whole 2643 * set. The size you get back when probing depends on what 2644 * you ask for. 2645 */ 2646 switch (namelen) { 2647 case 0: 2648 node.sysctl_size = n * sizeof(uint64_t); 2649 n = -2; /* ALL */ 2650 break; 2651 case 1: 2652 if (name[0] < 0 || name[0] >= n) 2653 return (ENOENT); /* ENOSUCHPROCESSOR */ 2654 node.sysctl_size = sizeof(uint64_t); 2655 n = name[0]; 2656 /* 2657 * adjust these so that sysctl_lookup() will be happy 2658 */ 2659 name++; 2660 namelen--; 2661 break; 2662 default: 2663 return (EINVAL); 2664 } 2665 2666 cp_id = kmem_alloc(node.sysctl_size, KM_SLEEP); 2667 if (cp_id == NULL) 2668 return (ENOMEM); 2669 node.sysctl_data = cp_id; 2670 memset(cp_id, 0, node.sysctl_size); 2671 2672 for (CPU_INFO_FOREACH(cii, ci)) { 2673 if (n <= 0) 2674 cp_id[0] = cpu_index(ci); 2675 /* 2676 * if a specific processor was requested and we just 2677 * did it, we're done here 2678 */ 2679 if (n == 0) 2680 break; 2681 /* 2682 * if doing "all", skip to next cp_id slot for next processor 2683 */ 2684 if (n == -2) 2685 cp_id++; 2686 /* 2687 * if we're doing a specific processor, we're one 2688 * processor closer 2689 */ 2690 if (n > 0) 2691 n--; 2692 } 2693 2694 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 2695 kmem_free(node.sysctl_data, node.sysctl_size); 2696 return (error); 2697 } 2698 2699 /* 2700 * sysctl helper routine for hw.usermem and hw.usermem64. Values are 2701 * calculate on the fly taking into account integer overflow and the 2702 * current wired count. 2703 */ 2704 static int 2705 sysctl_hw_usermem(SYSCTLFN_ARGS) 2706 { 2707 u_int ui; 2708 u_quad_t uq; 2709 struct sysctlnode node; 2710 2711 node = *rnode; 2712 switch (rnode->sysctl_num) { 2713 case HW_USERMEM: 2714 if ((ui = physmem - uvmexp.wired) > (UINT_MAX / PAGE_SIZE)) 2715 ui = UINT_MAX; 2716 else 2717 ui *= PAGE_SIZE; 2718 node.sysctl_data = &ui; 2719 break; 2720 case HW_USERMEM64: 2721 uq = (u_quad_t)(physmem - uvmexp.wired) * PAGE_SIZE; 2722 node.sysctl_data = &uq; 2723 break; 2724 default: 2725 return (EINVAL); 2726 } 2727 2728 return (sysctl_lookup(SYSCTLFN_CALL(&node))); 2729 } 2730 2731 /* 2732 * sysctl helper routine for kern.cnmagic node. Pulls the old value 2733 * out, encoded, and stuffs the new value in for decoding. 2734 */ 2735 static int 2736 sysctl_hw_cnmagic(SYSCTLFN_ARGS) 2737 { 2738 char magic[CNS_LEN]; 2739 int error; 2740 struct sysctlnode node; 2741 2742 if (oldp) 2743 cn_get_magic(magic, CNS_LEN); 2744 node = *rnode; 2745 node.sysctl_data = &magic[0]; 2746 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 2747 if (error || newp == NULL) 2748 return (error); 2749 2750 return (cn_set_magic(magic)); 2751 } 2752 2753 /* 2754 * ******************************************************************** 2755 * section 3: public helper routines that are used for more than one 2756 * node 2757 * ******************************************************************** 2758 */ 2759 2760 /* 2761 * sysctl helper routine for the kern.root_device node and some ports' 2762 * machdep.root_device nodes. 2763 */ 2764 int 2765 sysctl_root_device(SYSCTLFN_ARGS) 2766 { 2767 struct sysctlnode node; 2768 2769 node = *rnode; 2770 node.sysctl_data = root_device->dv_xname; 2771 node.sysctl_size = strlen(device_xname(root_device)) + 1; 2772 return (sysctl_lookup(SYSCTLFN_CALL(&node))); 2773 } 2774 2775 /* 2776 * sysctl helper routine for kern.consdev, dependent on the current 2777 * state of the console. Also used for machdep.console_device on some 2778 * ports. 2779 */ 2780 int 2781 sysctl_consdev(SYSCTLFN_ARGS) 2782 { 2783 dev_t consdev; 2784 uint32_t oconsdev; 2785 struct sysctlnode node; 2786 2787 if (cn_tab != NULL) 2788 consdev = cn_tab->cn_dev; 2789 else 2790 consdev = NODEV; 2791 node = *rnode; 2792 switch (*oldlenp) { 2793 case sizeof(consdev): 2794 node.sysctl_data = &consdev; 2795 node.sysctl_size = sizeof(consdev); 2796 break; 2797 case sizeof(oconsdev): 2798 oconsdev = (uint32_t)consdev; 2799 node.sysctl_data = &oconsdev; 2800 node.sysctl_size = sizeof(oconsdev); 2801 break; 2802 default: 2803 return EINVAL; 2804 } 2805 return (sysctl_lookup(SYSCTLFN_CALL(&node))); 2806 } 2807 2808 /* 2809 * ******************************************************************** 2810 * section 4: support for some helpers 2811 * ******************************************************************** 2812 */ 2813 /* 2814 * Find the most ``active'' lwp of a process and return it for ps display 2815 * purposes 2816 */ 2817 static struct lwp * 2818 proc_active_lwp(struct proc *p) 2819 { 2820 static const int ostat[] = { 2821 0, 2822 2, /* LSIDL */ 2823 6, /* LSRUN */ 2824 5, /* LSSLEEP */ 2825 4, /* LSSTOP */ 2826 0, /* LSZOMB */ 2827 1, /* LSDEAD */ 2828 7, /* LSONPROC */ 2829 3 /* LSSUSPENDED */ 2830 }; 2831 2832 struct lwp *l, *lp = NULL; 2833 LIST_FOREACH(l, &p->p_lwps, l_sibling) { 2834 KASSERT(l->l_stat >= 0 && l->l_stat < __arraycount(ostat)); 2835 if (lp == NULL || 2836 ostat[l->l_stat] > ostat[lp->l_stat] || 2837 (ostat[l->l_stat] == ostat[lp->l_stat] && 2838 l->l_cpticks > lp->l_cpticks)) { 2839 lp = l; 2840 continue; 2841 } 2842 } 2843 return lp; 2844 } 2845 2846 2847 /* 2848 * Fill in a kinfo_proc2 structure for the specified process. 2849 */ 2850 static void 2851 fill_kproc2(struct proc *p, struct kinfo_proc2 *ki, bool zombie) 2852 { 2853 struct tty *tp; 2854 struct lwp *l, *l2; 2855 struct timeval ut, st, rt; 2856 sigset_t ss1, ss2; 2857 struct rusage ru; 2858 struct vmspace *vm; 2859 2860 KASSERT(mutex_owned(proc_lock)); 2861 KASSERT(mutex_owned(p->p_lock)); 2862 2863 sigemptyset(&ss1); 2864 sigemptyset(&ss2); 2865 memset(ki, 0, sizeof(*ki)); 2866 2867 ki->p_paddr = PTRTOUINT64(p); 2868 ki->p_fd = PTRTOUINT64(p->p_fd); 2869 ki->p_cwdi = PTRTOUINT64(p->p_cwdi); 2870 ki->p_stats = PTRTOUINT64(p->p_stats); 2871 ki->p_limit = PTRTOUINT64(p->p_limit); 2872 ki->p_vmspace = PTRTOUINT64(p->p_vmspace); 2873 ki->p_sigacts = PTRTOUINT64(p->p_sigacts); 2874 ki->p_sess = PTRTOUINT64(p->p_session); 2875 ki->p_tsess = 0; /* may be changed if controlling tty below */ 2876 ki->p_ru = PTRTOUINT64(&p->p_stats->p_ru); 2877 ki->p_eflag = 0; 2878 ki->p_exitsig = p->p_exitsig; 2879 ki->p_flag = sysctl_map_flags(sysctl_flagmap, p->p_flag); 2880 ki->p_flag |= sysctl_map_flags(sysctl_sflagmap, p->p_sflag); 2881 ki->p_flag |= sysctl_map_flags(sysctl_slflagmap, p->p_slflag); 2882 ki->p_flag |= sysctl_map_flags(sysctl_lflagmap, p->p_lflag); 2883 ki->p_flag |= sysctl_map_flags(sysctl_stflagmap, p->p_stflag); 2884 ki->p_pid = p->p_pid; 2885 if (p->p_pptr) 2886 ki->p_ppid = p->p_pptr->p_pid; 2887 else 2888 ki->p_ppid = 0; 2889 ki->p_uid = kauth_cred_geteuid(p->p_cred); 2890 ki->p_ruid = kauth_cred_getuid(p->p_cred); 2891 ki->p_gid = kauth_cred_getegid(p->p_cred); 2892 ki->p_rgid = kauth_cred_getgid(p->p_cred); 2893 ki->p_svuid = kauth_cred_getsvuid(p->p_cred); 2894 ki->p_svgid = kauth_cred_getsvgid(p->p_cred); 2895 ki->p_ngroups = kauth_cred_ngroups(p->p_cred); 2896 kauth_cred_getgroups(p->p_cred, ki->p_groups, 2897 min(ki->p_ngroups, sizeof(ki->p_groups) / sizeof(ki->p_groups[0])), 2898 UIO_SYSSPACE); 2899 2900 ki->p_uticks = p->p_uticks; 2901 ki->p_sticks = p->p_sticks; 2902 ki->p_iticks = p->p_iticks; 2903 ki->p_tpgid = NO_PGID; /* may be changed if controlling tty below */ 2904 ki->p_tracep = PTRTOUINT64(p->p_tracep); 2905 ki->p_traceflag = p->p_traceflag; 2906 2907 memcpy(&ki->p_sigignore, &p->p_sigctx.ps_sigignore,sizeof(ki_sigset_t)); 2908 memcpy(&ki->p_sigcatch, &p->p_sigctx.ps_sigcatch, sizeof(ki_sigset_t)); 2909 2910 ki->p_cpticks = 0; 2911 ki->p_pctcpu = p->p_pctcpu; 2912 ki->p_estcpu = 0; 2913 ki->p_stat = p->p_stat; /* Will likely be overridden by LWP status */ 2914 ki->p_realstat = p->p_stat; 2915 ki->p_nice = p->p_nice; 2916 ki->p_xstat = p->p_xstat; 2917 ki->p_acflag = p->p_acflag; 2918 2919 strncpy(ki->p_comm, p->p_comm, 2920 min(sizeof(ki->p_comm), sizeof(p->p_comm))); 2921 strncpy(ki->p_ename, p->p_emul->e_name, sizeof(ki->p_ename)); 2922 2923 ki->p_nlwps = p->p_nlwps; 2924 ki->p_realflag = ki->p_flag; 2925 2926 if (p->p_stat != SIDL && !P_ZOMBIE(p) && !zombie) { 2927 vm = p->p_vmspace; 2928 ki->p_vm_rssize = vm_resident_count(vm); 2929 ki->p_vm_tsize = vm->vm_tsize; 2930 ki->p_vm_dsize = vm->vm_dsize; 2931 ki->p_vm_ssize = vm->vm_ssize; 2932 ki->p_vm_vsize = vm->vm_map.size; 2933 /* 2934 * Since the stack is initially mapped mostly with 2935 * PROT_NONE and grown as needed, adjust the "mapped size" 2936 * to skip the unused stack portion. 2937 */ 2938 ki->p_vm_msize = 2939 atop(vm->vm_map.size) - vm->vm_issize + vm->vm_ssize; 2940 2941 /* Pick the primary (first) LWP */ 2942 l = proc_active_lwp(p); 2943 KASSERT(l != NULL); 2944 lwp_lock(l); 2945 ki->p_nrlwps = p->p_nrlwps; 2946 ki->p_forw = 0; 2947 ki->p_back = 0; 2948 ki->p_addr = PTRTOUINT64(l->l_addr); 2949 ki->p_stat = l->l_stat; 2950 ki->p_flag |= sysctl_map_flags(sysctl_lwpflagmap, l->l_flag); 2951 ki->p_swtime = l->l_swtime; 2952 ki->p_slptime = l->l_slptime; 2953 if (l->l_stat == LSONPROC) 2954 ki->p_schedflags = l->l_cpu->ci_schedstate.spc_flags; 2955 else 2956 ki->p_schedflags = 0; 2957 ki->p_holdcnt = l->l_holdcnt; 2958 ki->p_priority = lwp_eprio(l); 2959 ki->p_usrpri = l->l_priority; 2960 if (l->l_wchan) 2961 strncpy(ki->p_wmesg, l->l_wmesg, sizeof(ki->p_wmesg)); 2962 ki->p_wchan = PTRTOUINT64(l->l_wchan); 2963 ki->p_cpuid = cpu_index(l->l_cpu); 2964 lwp_unlock(l); 2965 LIST_FOREACH(l, &p->p_lwps, l_sibling) { 2966 /* This is hardly correct, but... */ 2967 sigplusset(&l->l_sigpend.sp_set, &ss1); 2968 sigplusset(&l->l_sigmask, &ss2); 2969 ki->p_cpticks += l->l_cpticks; 2970 ki->p_pctcpu += l->l_pctcpu; 2971 ki->p_estcpu += l->l_estcpu; 2972 } 2973 } 2974 sigplusset(&p->p_sigpend.sp_set, &ss2); 2975 memcpy(&ki->p_siglist, &ss1, sizeof(ki_sigset_t)); 2976 memcpy(&ki->p_sigmask, &ss2, sizeof(ki_sigset_t)); 2977 2978 if (p->p_session != NULL) { 2979 ki->p_sid = p->p_session->s_sid; 2980 ki->p__pgid = p->p_pgrp->pg_id; 2981 if (p->p_session->s_ttyvp) 2982 ki->p_eflag |= EPROC_CTTY; 2983 if (SESS_LEADER(p)) 2984 ki->p_eflag |= EPROC_SLEADER; 2985 strncpy(ki->p_login, p->p_session->s_login, 2986 min(sizeof ki->p_login - 1, sizeof p->p_session->s_login)); 2987 ki->p_jobc = p->p_pgrp->pg_jobc; 2988 if ((p->p_lflag & PL_CONTROLT) && (tp = p->p_session->s_ttyp)) { 2989 ki->p_tdev = tp->t_dev; 2990 ki->p_tpgid = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PGID; 2991 ki->p_tsess = PTRTOUINT64(tp->t_session); 2992 } else { 2993 ki->p_tdev = (int32_t)NODEV; 2994 } 2995 } 2996 2997 if (!P_ZOMBIE(p) && !zombie) { 2998 ki->p_uvalid = 1; 2999 ki->p_ustart_sec = p->p_stats->p_start.tv_sec; 3000 ki->p_ustart_usec = p->p_stats->p_start.tv_usec; 3001 3002 calcru(p, &ut, &st, NULL, &rt); 3003 ki->p_rtime_sec = rt.tv_sec; 3004 ki->p_rtime_usec = rt.tv_usec; 3005 ki->p_uutime_sec = ut.tv_sec; 3006 ki->p_uutime_usec = ut.tv_usec; 3007 ki->p_ustime_sec = st.tv_sec; 3008 ki->p_ustime_usec = st.tv_usec; 3009 3010 memcpy(&ru, &p->p_stats->p_ru, sizeof(ru)); 3011 ki->p_uru_nvcsw = 0; 3012 ki->p_uru_nivcsw = 0; 3013 LIST_FOREACH(l2, &p->p_lwps, l_sibling) { 3014 ki->p_uru_nvcsw += (l2->l_ncsw - l2->l_nivcsw); 3015 ki->p_uru_nivcsw += l2->l_nivcsw; 3016 ruadd(&ru, &l2->l_ru); 3017 } 3018 ki->p_uru_maxrss = ru.ru_maxrss; 3019 ki->p_uru_ixrss = ru.ru_ixrss; 3020 ki->p_uru_idrss = ru.ru_idrss; 3021 ki->p_uru_isrss = ru.ru_isrss; 3022 ki->p_uru_minflt = ru.ru_minflt; 3023 ki->p_uru_majflt = ru.ru_majflt; 3024 ki->p_uru_nswap = ru.ru_nswap; 3025 ki->p_uru_inblock = ru.ru_inblock; 3026 ki->p_uru_oublock = ru.ru_oublock; 3027 ki->p_uru_msgsnd = ru.ru_msgsnd; 3028 ki->p_uru_msgrcv = ru.ru_msgrcv; 3029 ki->p_uru_nsignals = ru.ru_nsignals; 3030 3031 timeradd(&p->p_stats->p_cru.ru_utime, 3032 &p->p_stats->p_cru.ru_stime, &ut); 3033 ki->p_uctime_sec = ut.tv_sec; 3034 ki->p_uctime_usec = ut.tv_usec; 3035 } 3036 } 3037 3038 /* 3039 * Fill in a kinfo_lwp structure for the specified lwp. 3040 */ 3041 static void 3042 fill_lwp(struct lwp *l, struct kinfo_lwp *kl) 3043 { 3044 struct proc *p = l->l_proc; 3045 struct timeval tv; 3046 3047 KASSERT(lwp_locked(l, NULL)); 3048 3049 kl->l_forw = 0; 3050 kl->l_back = 0; 3051 kl->l_laddr = PTRTOUINT64(l); 3052 kl->l_addr = PTRTOUINT64(l->l_addr); 3053 kl->l_stat = l->l_stat; 3054 kl->l_lid = l->l_lid; 3055 kl->l_flag = sysctl_map_flags(sysctl_lwpprflagmap, l->l_prflag); 3056 kl->l_flag |= sysctl_map_flags(sysctl_lwpflagmap, l->l_flag); 3057 3058 kl->l_swtime = l->l_swtime; 3059 kl->l_slptime = l->l_slptime; 3060 if (l->l_stat == LSONPROC) 3061 kl->l_schedflags = l->l_cpu->ci_schedstate.spc_flags; 3062 else 3063 kl->l_schedflags = 0; 3064 kl->l_holdcnt = l->l_holdcnt; 3065 kl->l_priority = lwp_eprio(l); 3066 kl->l_usrpri = l->l_priority; 3067 if (l->l_wchan) 3068 strncpy(kl->l_wmesg, l->l_wmesg, sizeof(kl->l_wmesg)); 3069 kl->l_wchan = PTRTOUINT64(l->l_wchan); 3070 kl->l_cpuid = cpu_index(l->l_cpu); 3071 bintime2timeval(&l->l_rtime, &tv); 3072 kl->l_rtime_sec = tv.tv_sec; 3073 kl->l_rtime_usec = tv.tv_usec; 3074 kl->l_cpticks = l->l_cpticks; 3075 kl->l_pctcpu = l->l_pctcpu; 3076 kl->l_pid = p->p_pid; 3077 if (l->l_name == NULL) 3078 kl->l_name[0] = '\0'; 3079 else 3080 strlcpy(kl->l_name, l->l_name, sizeof(kl->l_name)); 3081 } 3082 3083 /* 3084 * Fill in an eproc structure for the specified process. 3085 */ 3086 void 3087 fill_eproc(struct proc *p, struct eproc *ep, bool zombie) 3088 { 3089 struct tty *tp; 3090 struct lwp *l; 3091 3092 KASSERT(mutex_owned(proc_lock)); 3093 KASSERT(mutex_owned(p->p_lock)); 3094 3095 memset(ep, 0, sizeof(*ep)); 3096 3097 ep->e_paddr = p; 3098 ep->e_sess = p->p_session; 3099 if (p->p_cred) { 3100 kauth_cred_topcred(p->p_cred, &ep->e_pcred); 3101 kauth_cred_toucred(p->p_cred, &ep->e_ucred); 3102 } 3103 if (p->p_stat != SIDL && !P_ZOMBIE(p) && !zombie) { 3104 struct vmspace *vm = p->p_vmspace; 3105 3106 ep->e_vm.vm_rssize = vm_resident_count(vm); 3107 ep->e_vm.vm_tsize = vm->vm_tsize; 3108 ep->e_vm.vm_dsize = vm->vm_dsize; 3109 ep->e_vm.vm_ssize = vm->vm_ssize; 3110 ep->e_vm.vm_map.size = vm->vm_map.size; 3111 3112 /* Pick the primary (first) LWP */ 3113 l = proc_active_lwp(p); 3114 KASSERT(l != NULL); 3115 lwp_lock(l); 3116 if (l->l_wchan) 3117 strncpy(ep->e_wmesg, l->l_wmesg, WMESGLEN); 3118 lwp_unlock(l); 3119 } 3120 if (p->p_pptr) 3121 ep->e_ppid = p->p_pptr->p_pid; 3122 if (p->p_pgrp && p->p_session) { 3123 ep->e_pgid = p->p_pgrp->pg_id; 3124 ep->e_jobc = p->p_pgrp->pg_jobc; 3125 ep->e_sid = p->p_session->s_sid; 3126 if ((p->p_lflag & PL_CONTROLT) && 3127 (tp = ep->e_sess->s_ttyp)) { 3128 ep->e_tdev = tp->t_dev; 3129 ep->e_tpgid = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PGID; 3130 ep->e_tsess = tp->t_session; 3131 } else 3132 ep->e_tdev = (uint32_t)NODEV; 3133 ep->e_flag = ep->e_sess->s_ttyvp ? EPROC_CTTY : 0; 3134 if (SESS_LEADER(p)) 3135 ep->e_flag |= EPROC_SLEADER; 3136 strncpy(ep->e_login, ep->e_sess->s_login, MAXLOGNAME); 3137 } 3138 ep->e_xsize = ep->e_xrssize = 0; 3139 ep->e_xccount = ep->e_xswrss = 0; 3140 } 3141 3142 u_int 3143 sysctl_map_flags(const u_int *map, u_int word) 3144 { 3145 u_int rv; 3146 3147 for (rv = 0; *map != 0; map += 2) 3148 if ((word & map[0]) != 0) 3149 rv |= map[1]; 3150 3151 return rv; 3152 } 3153