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