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