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