1 /* $OpenBSD: kern_sysctl.c,v 1.427 2024/04/12 16:07:09 bluhm Exp $ */ 2 /* $NetBSD: kern_sysctl.c,v 1.17 1996/05/20 17:49:05 mrg Exp $ */ 3 4 /*- 5 * Copyright (c) 1982, 1986, 1989, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * This code is derived from software contributed to Berkeley by 9 * Mike Karels at Berkeley Software Design, Inc. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. Neither the name of the University nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 * 35 * @(#)kern_sysctl.c 8.4 (Berkeley) 4/14/94 36 */ 37 38 /* 39 * sysctl system call. 40 */ 41 42 #include <sys/param.h> 43 #include <sys/systm.h> 44 #include <sys/kernel.h> 45 #include <sys/malloc.h> 46 #include <sys/pool.h> 47 #include <sys/proc.h> 48 #include <sys/resourcevar.h> 49 #include <sys/signalvar.h> 50 #include <sys/fcntl.h> 51 #include <sys/file.h> 52 #include <sys/filedesc.h> 53 #include <sys/vnode.h> 54 #include <sys/unistd.h> 55 #include <sys/buf.h> 56 #include <sys/clockintr.h> 57 #include <sys/tty.h> 58 #include <sys/disklabel.h> 59 #include <sys/disk.h> 60 #include <sys/sysctl.h> 61 #include <sys/msgbuf.h> 62 #include <sys/vmmeter.h> 63 #include <sys/namei.h> 64 #include <sys/exec.h> 65 #include <sys/mbuf.h> 66 #include <sys/percpu.h> 67 #include <sys/sensors.h> 68 #include <sys/pipe.h> 69 #include <sys/eventvar.h> 70 #include <sys/socketvar.h> 71 #include <sys/socket.h> 72 #include <sys/domain.h> 73 #include <sys/protosw.h> 74 #include <sys/pledge.h> 75 #include <sys/timetc.h> 76 #include <sys/evcount.h> 77 #include <sys/un.h> 78 #include <sys/unpcb.h> 79 #include <sys/sched.h> 80 #include <sys/mount.h> 81 #include <sys/syscallargs.h> 82 #include <sys/wait.h> 83 #include <sys/witness.h> 84 85 #include <uvm/uvm_extern.h> 86 87 #include <dev/cons.h> 88 89 #include <dev/usb/ucomvar.h> 90 91 #include <net/route.h> 92 #include <netinet/in.h> 93 #include <netinet/ip.h> 94 #include <netinet/ip_var.h> 95 #include <netinet/in_pcb.h> 96 #include <netinet/ip6.h> 97 #include <netinet/tcp.h> 98 #include <netinet/tcp_timer.h> 99 #include <netinet/tcp_var.h> 100 #include <netinet/udp.h> 101 #include <netinet/udp_var.h> 102 #include <netinet6/ip6_var.h> 103 104 #ifdef DDB 105 #include <ddb/db_var.h> 106 #endif 107 108 #ifdef SYSVMSG 109 #include <sys/msg.h> 110 #endif 111 #ifdef SYSVSEM 112 #include <sys/sem.h> 113 #endif 114 #ifdef SYSVSHM 115 #include <sys/shm.h> 116 #endif 117 118 #include "audio.h" 119 #include "dt.h" 120 #include "pf.h" 121 #include "ucom.h" 122 #include "video.h" 123 124 extern struct forkstat forkstat; 125 extern struct nchstats nchstats; 126 extern int fscale; 127 extern fixpt_t ccpu; 128 extern long numvnodes; 129 extern int allowdt; 130 extern int audio_record_enable; 131 extern int video_record_enable; 132 extern int autoconf_serial; 133 134 int allowkmem; 135 136 int sysctl_diskinit(int, struct proc *); 137 int sysctl_proc_args(int *, u_int, void *, size_t *, struct proc *); 138 int sysctl_proc_cwd(int *, u_int, void *, size_t *, struct proc *); 139 int sysctl_proc_nobroadcastkill(int *, u_int, void *, size_t, void *, size_t *, 140 struct proc *); 141 int sysctl_proc_vmmap(int *, u_int, void *, size_t *, struct proc *); 142 int sysctl_intrcnt(int *, u_int, void *, size_t *); 143 int sysctl_sensors(int *, u_int, void *, size_t *, void *, size_t); 144 int sysctl_cptime2(int *, u_int, void *, size_t *, void *, size_t); 145 int sysctl_audio(int *, u_int, void *, size_t *, void *, size_t); 146 int sysctl_video(int *, u_int, void *, size_t *, void *, size_t); 147 int sysctl_cpustats(int *, u_int, void *, size_t *, void *, size_t); 148 int sysctl_utc_offset(void *, size_t *, void *, size_t); 149 int sysctl_hwbattery(int *, u_int, void *, size_t *, void *, size_t); 150 151 void fill_file(struct kinfo_file *, struct file *, struct filedesc *, int, 152 struct vnode *, struct process *, struct proc *, struct socket *, int); 153 void fill_kproc(struct process *, struct kinfo_proc *, struct proc *, int); 154 155 int (*cpu_cpuspeed)(int *); 156 157 /* 158 * Lock to avoid too many processes vslocking a large amount of memory 159 * at the same time. 160 */ 161 struct rwlock sysctl_lock = RWLOCK_INITIALIZER("sysctllk"); 162 struct rwlock sysctl_disklock = RWLOCK_INITIALIZER("sysctldlk"); 163 164 int 165 sys_sysctl(struct proc *p, void *v, register_t *retval) 166 { 167 struct sys_sysctl_args /* { 168 syscallarg(const int *) name; 169 syscallarg(u_int) namelen; 170 syscallarg(void *) old; 171 syscallarg(size_t *) oldlenp; 172 syscallarg(void *) new; 173 syscallarg(size_t) newlen; 174 } */ *uap = v; 175 int error, dolock = 1; 176 size_t savelen = 0, oldlen = 0; 177 sysctlfn *fn; 178 int name[CTL_MAXNAME]; 179 180 if (SCARG(uap, new) != NULL && 181 (error = suser(p))) 182 return (error); 183 /* 184 * all top-level sysctl names are non-terminal 185 */ 186 if (SCARG(uap, namelen) > CTL_MAXNAME || SCARG(uap, namelen) < 2) 187 return (EINVAL); 188 error = copyin(SCARG(uap, name), name, 189 SCARG(uap, namelen) * sizeof(int)); 190 if (error) 191 return (error); 192 193 error = pledge_sysctl(p, SCARG(uap, namelen), 194 name, SCARG(uap, new)); 195 if (error) 196 return (error); 197 198 switch (name[0]) { 199 case CTL_KERN: 200 fn = kern_sysctl; 201 break; 202 case CTL_HW: 203 fn = hw_sysctl; 204 break; 205 case CTL_VM: 206 fn = uvm_sysctl; 207 break; 208 case CTL_NET: 209 fn = net_sysctl; 210 break; 211 case CTL_FS: 212 fn = fs_sysctl; 213 break; 214 case CTL_VFS: 215 fn = vfs_sysctl; 216 break; 217 case CTL_MACHDEP: 218 fn = cpu_sysctl; 219 break; 220 #ifdef DEBUG_SYSCTL 221 case CTL_DEBUG: 222 fn = debug_sysctl; 223 break; 224 #endif 225 #ifdef DDB 226 case CTL_DDB: 227 fn = ddb_sysctl; 228 break; 229 #endif 230 default: 231 return (EOPNOTSUPP); 232 } 233 234 if (SCARG(uap, oldlenp) && 235 (error = copyin(SCARG(uap, oldlenp), &oldlen, sizeof(oldlen)))) 236 return (error); 237 if (SCARG(uap, old) != NULL) { 238 if ((error = rw_enter(&sysctl_lock, RW_WRITE|RW_INTR)) != 0) 239 return (error); 240 if (dolock) { 241 if (atop(oldlen) > uvmexp.wiredmax - uvmexp.wired) { 242 rw_exit_write(&sysctl_lock); 243 return (ENOMEM); 244 } 245 error = uvm_vslock(p, SCARG(uap, old), oldlen, 246 PROT_READ | PROT_WRITE); 247 if (error) { 248 rw_exit_write(&sysctl_lock); 249 return (error); 250 } 251 } 252 savelen = oldlen; 253 } 254 error = (*fn)(&name[1], SCARG(uap, namelen) - 1, SCARG(uap, old), 255 &oldlen, SCARG(uap, new), SCARG(uap, newlen), p); 256 if (SCARG(uap, old) != NULL) { 257 if (dolock) 258 uvm_vsunlock(p, SCARG(uap, old), savelen); 259 rw_exit_write(&sysctl_lock); 260 } 261 if (error) 262 return (error); 263 if (SCARG(uap, oldlenp)) 264 error = copyout(&oldlen, SCARG(uap, oldlenp), sizeof(oldlen)); 265 return (error); 266 } 267 268 /* 269 * Attributes stored in the kernel. 270 */ 271 char hostname[MAXHOSTNAMELEN]; 272 int hostnamelen; 273 char domainname[MAXHOSTNAMELEN]; 274 int domainnamelen; 275 long hostid; 276 char *disknames = NULL; 277 size_t disknameslen; 278 struct diskstats *diskstats = NULL; 279 size_t diskstatslen; 280 int securelevel; 281 282 /* morally const values reported by sysctl_bounded_arr */ 283 static int arg_max = ARG_MAX; 284 static int openbsd = OpenBSD; 285 static int posix_version = _POSIX_VERSION; 286 static int ngroups_max = NGROUPS_MAX; 287 static int int_zero = 0; 288 static int int_one = 1; 289 static int maxpartitions = MAXPARTITIONS; 290 static int raw_part = RAW_PART; 291 292 extern int somaxconn, sominconn; 293 extern int nosuidcoredump; 294 extern int maxlocksperuid; 295 extern int uvm_wxabort; 296 extern int global_ptrace; 297 298 const struct sysctl_bounded_args kern_vars[] = { 299 {KERN_OSREV, &openbsd, SYSCTL_INT_READONLY}, 300 {KERN_MAXVNODES, &maxvnodes, 0, INT_MAX}, 301 {KERN_MAXPROC, &maxprocess, 0, INT_MAX}, 302 {KERN_MAXFILES, &maxfiles, 0, INT_MAX}, 303 {KERN_NFILES, &numfiles, SYSCTL_INT_READONLY}, 304 {KERN_TTYCOUNT, &tty_count, SYSCTL_INT_READONLY}, 305 {KERN_ARGMAX, &arg_max, SYSCTL_INT_READONLY}, 306 {KERN_POSIX1, &posix_version, SYSCTL_INT_READONLY}, 307 {KERN_NGROUPS, &ngroups_max, SYSCTL_INT_READONLY}, 308 {KERN_JOB_CONTROL, &int_one, SYSCTL_INT_READONLY}, 309 {KERN_SAVED_IDS, &int_one, SYSCTL_INT_READONLY}, 310 {KERN_MAXPARTITIONS, &maxpartitions, SYSCTL_INT_READONLY}, 311 {KERN_RAWPARTITION, &raw_part, SYSCTL_INT_READONLY}, 312 {KERN_MAXTHREAD, &maxthread, 0, INT_MAX}, 313 {KERN_NTHREADS, &nthreads, SYSCTL_INT_READONLY}, 314 {KERN_SOMAXCONN, &somaxconn, 0, SHRT_MAX}, 315 {KERN_SOMINCONN, &sominconn, 0, SHRT_MAX}, 316 {KERN_NOSUIDCOREDUMP, &nosuidcoredump, 0, 3}, 317 {KERN_FSYNC, &int_one, SYSCTL_INT_READONLY}, 318 {KERN_SYSVMSG, 319 #ifdef SYSVMSG 320 &int_one, 321 #else 322 &int_zero, 323 #endif 324 SYSCTL_INT_READONLY}, 325 {KERN_SYSVSEM, 326 #ifdef SYSVSEM 327 &int_one, 328 #else 329 &int_zero, 330 #endif 331 SYSCTL_INT_READONLY}, 332 {KERN_SYSVSHM, 333 #ifdef SYSVSHM 334 &int_one, 335 #else 336 &int_zero, 337 #endif 338 SYSCTL_INT_READONLY}, 339 {KERN_FSCALE, &fscale, SYSCTL_INT_READONLY}, 340 {KERN_CCPU, &ccpu, SYSCTL_INT_READONLY}, 341 {KERN_NPROCS, &nprocesses, SYSCTL_INT_READONLY}, 342 {KERN_SPLASSERT, &splassert_ctl, 0, 3}, 343 {KERN_MAXLOCKSPERUID, &maxlocksperuid, 0, INT_MAX}, 344 {KERN_WXABORT, &uvm_wxabort, 0, 1}, 345 {KERN_NETLIVELOCKS, &int_zero, SYSCTL_INT_READONLY}, 346 #ifdef PTRACE 347 {KERN_GLOBAL_PTRACE, &global_ptrace, 0, 1}, 348 #endif 349 {KERN_AUTOCONF_SERIAL, &autoconf_serial, SYSCTL_INT_READONLY}, 350 }; 351 352 int 353 kern_sysctl_dirs(int top_name, int *name, u_int namelen, 354 void *oldp, size_t *oldlenp, void *newp, size_t newlen, struct proc *p) 355 { 356 switch (top_name) { 357 #ifndef SMALL_KERNEL 358 case KERN_PROC: 359 return (sysctl_doproc(name, namelen, oldp, oldlenp)); 360 case KERN_PROC_ARGS: 361 return (sysctl_proc_args(name, namelen, oldp, oldlenp, p)); 362 case KERN_PROC_CWD: 363 return (sysctl_proc_cwd(name, namelen, oldp, oldlenp, p)); 364 case KERN_PROC_NOBROADCASTKILL: 365 return (sysctl_proc_nobroadcastkill(name, namelen, 366 newp, newlen, oldp, oldlenp, p)); 367 case KERN_PROC_VMMAP: 368 return (sysctl_proc_vmmap(name, namelen, oldp, oldlenp, p)); 369 case KERN_FILE: 370 return (sysctl_file(name, namelen, oldp, oldlenp, p)); 371 #endif 372 #if defined(GPROF) || defined(DDBPROF) 373 case KERN_PROF: 374 return (sysctl_doprof(name, namelen, oldp, oldlenp, 375 newp, newlen)); 376 #endif 377 case KERN_MALLOCSTATS: 378 return (sysctl_malloc(name, namelen, oldp, oldlenp, 379 newp, newlen, p)); 380 case KERN_TTY: 381 return (sysctl_tty(name, namelen, oldp, oldlenp, 382 newp, newlen)); 383 case KERN_POOL: 384 return (sysctl_dopool(name, namelen, oldp, oldlenp)); 385 #if defined(SYSVMSG) || defined(SYSVSEM) || defined(SYSVSHM) 386 case KERN_SYSVIPC_INFO: 387 return (sysctl_sysvipc(name, namelen, oldp, oldlenp)); 388 #endif 389 #ifdef SYSVSEM 390 case KERN_SEMINFO: 391 return (sysctl_sysvsem(name, namelen, oldp, oldlenp, 392 newp, newlen)); 393 #endif 394 #ifdef SYSVSHM 395 case KERN_SHMINFO: 396 return (sysctl_sysvshm(name, namelen, oldp, oldlenp, 397 newp, newlen)); 398 #endif 399 #ifndef SMALL_KERNEL 400 case KERN_INTRCNT: 401 return (sysctl_intrcnt(name, namelen, oldp, oldlenp)); 402 case KERN_WATCHDOG: 403 return (sysctl_wdog(name, namelen, oldp, oldlenp, 404 newp, newlen)); 405 #endif 406 #ifndef SMALL_KERNEL 407 case KERN_EVCOUNT: 408 return (evcount_sysctl(name, namelen, oldp, oldlenp, 409 newp, newlen)); 410 #endif 411 case KERN_TIMECOUNTER: 412 return (sysctl_tc(name, namelen, oldp, oldlenp, newp, newlen)); 413 case KERN_CPTIME2: 414 return (sysctl_cptime2(name, namelen, oldp, oldlenp, 415 newp, newlen)); 416 #ifdef WITNESS 417 case KERN_WITNESSWATCH: 418 return witness_sysctl_watch(oldp, oldlenp, newp, newlen); 419 case KERN_WITNESS: 420 return witness_sysctl(name, namelen, oldp, oldlenp, 421 newp, newlen); 422 #endif 423 #if NAUDIO > 0 424 case KERN_AUDIO: 425 return (sysctl_audio(name, namelen, oldp, oldlenp, 426 newp, newlen)); 427 #endif 428 #if NVIDEO > 0 429 case KERN_VIDEO: 430 return (sysctl_video(name, namelen, oldp, oldlenp, 431 newp, newlen)); 432 #endif 433 case KERN_CPUSTATS: 434 return (sysctl_cpustats(name, namelen, oldp, oldlenp, 435 newp, newlen)); 436 case KERN_CLOCKINTR: 437 return sysctl_clockintr(name, namelen, oldp, oldlenp, newp, 438 newlen); 439 default: 440 return (ENOTDIR); /* overloaded */ 441 } 442 } 443 444 /* 445 * kernel related system variables. 446 */ 447 int 448 kern_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, 449 size_t newlen, struct proc *p) 450 { 451 int error, level, inthostid, stackgap; 452 dev_t dev; 453 extern int pool_debug; 454 455 /* dispatch the non-terminal nodes first */ 456 if (namelen != 1) { 457 return kern_sysctl_dirs(name[0], name + 1, namelen - 1, 458 oldp, oldlenp, newp, newlen, p); 459 } 460 461 switch (name[0]) { 462 case KERN_OSTYPE: 463 return (sysctl_rdstring(oldp, oldlenp, newp, ostype)); 464 case KERN_OSRELEASE: 465 return (sysctl_rdstring(oldp, oldlenp, newp, osrelease)); 466 case KERN_OSVERSION: 467 return (sysctl_rdstring(oldp, oldlenp, newp, osversion)); 468 case KERN_VERSION: 469 return (sysctl_rdstring(oldp, oldlenp, newp, version)); 470 case KERN_NUMVNODES: /* XXX numvnodes is a long */ 471 return (sysctl_rdint(oldp, oldlenp, newp, numvnodes)); 472 case KERN_SECURELVL: 473 level = securelevel; 474 if ((error = sysctl_int(oldp, oldlenp, newp, newlen, &level)) || 475 newp == NULL) 476 return (error); 477 if ((securelevel > 0 || level < -1) && 478 level < securelevel && p->p_p->ps_pid != 1) 479 return (EPERM); 480 securelevel = level; 481 return (0); 482 #if NDT > 0 483 case KERN_ALLOWDT: 484 return (sysctl_securelevel_int(oldp, oldlenp, newp, newlen, 485 &allowdt)); 486 #endif 487 case KERN_ALLOWKMEM: 488 return (sysctl_securelevel_int(oldp, oldlenp, newp, newlen, 489 &allowkmem)); 490 case KERN_HOSTNAME: 491 error = sysctl_tstring(oldp, oldlenp, newp, newlen, 492 hostname, sizeof(hostname)); 493 if (newp && !error) 494 hostnamelen = newlen; 495 return (error); 496 case KERN_DOMAINNAME: 497 if (securelevel >= 1 && domainnamelen && newp) 498 error = EPERM; 499 else 500 error = sysctl_tstring(oldp, oldlenp, newp, newlen, 501 domainname, sizeof(domainname)); 502 if (newp && !error) 503 domainnamelen = newlen; 504 return (error); 505 case KERN_HOSTID: 506 inthostid = hostid; /* XXX assumes sizeof long <= sizeof int */ 507 error = sysctl_int(oldp, oldlenp, newp, newlen, &inthostid); 508 hostid = inthostid; 509 return (error); 510 case KERN_CLOCKRATE: 511 return (sysctl_clockrate(oldp, oldlenp, newp)); 512 case KERN_BOOTTIME: { 513 struct timeval bt; 514 memset(&bt, 0, sizeof bt); 515 microboottime(&bt); 516 return (sysctl_rdstruct(oldp, oldlenp, newp, &bt, sizeof bt)); 517 } 518 case KERN_MBSTAT: { 519 extern struct cpumem *mbstat; 520 uint64_t counters[MBSTAT_COUNT]; 521 struct mbstat mbs; 522 unsigned int i; 523 524 memset(&mbs, 0, sizeof(mbs)); 525 counters_read(mbstat, counters, MBSTAT_COUNT, NULL); 526 for (i = 0; i < MBSTAT_TYPES; i++) 527 mbs.m_mtypes[i] = counters[i]; 528 529 mbs.m_drops = counters[MBSTAT_DROPS]; 530 mbs.m_wait = counters[MBSTAT_WAIT]; 531 mbs.m_drain = counters[MBSTAT_DRAIN]; 532 533 return (sysctl_rdstruct(oldp, oldlenp, newp, 534 &mbs, sizeof(mbs))); 535 } 536 case KERN_MSGBUFSIZE: 537 case KERN_CONSBUFSIZE: { 538 struct msgbuf *mp; 539 mp = (name[0] == KERN_MSGBUFSIZE) ? msgbufp : consbufp; 540 /* 541 * deal with cases where the message buffer has 542 * become corrupted. 543 */ 544 if (!mp || mp->msg_magic != MSG_MAGIC) 545 return (ENXIO); 546 return (sysctl_rdint(oldp, oldlenp, newp, mp->msg_bufs)); 547 } 548 case KERN_CONSBUF: 549 if ((error = suser(p))) 550 return (error); 551 /* FALLTHROUGH */ 552 case KERN_MSGBUF: { 553 struct msgbuf *mp; 554 mp = (name[0] == KERN_MSGBUF) ? msgbufp : consbufp; 555 /* see note above */ 556 if (!mp || mp->msg_magic != MSG_MAGIC) 557 return (ENXIO); 558 return (sysctl_rdstruct(oldp, oldlenp, newp, mp, 559 mp->msg_bufs + offsetof(struct msgbuf, msg_bufc))); 560 } 561 case KERN_CPTIME: 562 { 563 CPU_INFO_ITERATOR cii; 564 struct cpu_info *ci; 565 long cp_time[CPUSTATES]; 566 int i, n = 0; 567 568 memset(cp_time, 0, sizeof(cp_time)); 569 570 CPU_INFO_FOREACH(cii, ci) { 571 if (!cpu_is_online(ci)) 572 continue; 573 n++; 574 for (i = 0; i < CPUSTATES; i++) 575 cp_time[i] += ci->ci_schedstate.spc_cp_time[i]; 576 } 577 578 for (i = 0; i < CPUSTATES; i++) 579 cp_time[i] /= n; 580 581 return (sysctl_rdstruct(oldp, oldlenp, newp, &cp_time, 582 sizeof(cp_time))); 583 } 584 case KERN_NCHSTATS: 585 return (sysctl_rdstruct(oldp, oldlenp, newp, &nchstats, 586 sizeof(struct nchstats))); 587 case KERN_FORKSTAT: 588 return (sysctl_rdstruct(oldp, oldlenp, newp, &forkstat, 589 sizeof(struct forkstat))); 590 case KERN_STACKGAPRANDOM: 591 stackgap = stackgap_random; 592 error = sysctl_int(oldp, oldlenp, newp, newlen, &stackgap); 593 if (error) 594 return (error); 595 /* 596 * Safety harness. 597 */ 598 if ((stackgap < ALIGNBYTES && stackgap != 0) || 599 !powerof2(stackgap) || stackgap >= MAXSSIZ) 600 return (EINVAL); 601 stackgap_random = stackgap; 602 return (0); 603 case KERN_MAXCLUSTERS: { 604 int val = nmbclust; 605 error = sysctl_int(oldp, oldlenp, newp, newlen, &val); 606 if (error == 0 && val != nmbclust) 607 error = nmbclust_update(val); 608 return (error); 609 } 610 case KERN_CACHEPCT: { 611 u_int64_t dmapages; 612 int opct, pgs; 613 opct = bufcachepercent; 614 error = sysctl_int(oldp, oldlenp, newp, newlen, 615 &bufcachepercent); 616 if (error) 617 return(error); 618 if (bufcachepercent > 90 || bufcachepercent < 5) { 619 bufcachepercent = opct; 620 return (EINVAL); 621 } 622 dmapages = uvm_pagecount(&dma_constraint); 623 if (bufcachepercent != opct) { 624 pgs = bufcachepercent * dmapages / 100; 625 bufadjust(pgs); /* adjust bufpages */ 626 bufhighpages = bufpages; /* set high water mark */ 627 } 628 return(0); 629 } 630 case KERN_CONSDEV: 631 if (cn_tab != NULL) 632 dev = cn_tab->cn_dev; 633 else 634 dev = NODEV; 635 return sysctl_rdstruct(oldp, oldlenp, newp, &dev, sizeof(dev)); 636 case KERN_POOL_DEBUG: { 637 int old_pool_debug = pool_debug; 638 639 error = sysctl_int(oldp, oldlenp, newp, newlen, 640 &pool_debug); 641 if (error == 0 && pool_debug != old_pool_debug) 642 pool_reclaim_all(); 643 return (error); 644 } 645 #if NPF > 0 646 case KERN_PFSTATUS: 647 return (pf_sysctl(oldp, oldlenp, newp, newlen)); 648 #endif 649 case KERN_TIMEOUT_STATS: 650 return (timeout_sysctl(oldp, oldlenp, newp, newlen)); 651 case KERN_UTC_OFFSET: 652 return (sysctl_utc_offset(oldp, oldlenp, newp, newlen)); 653 default: 654 return (sysctl_bounded_arr(kern_vars, nitems(kern_vars), name, 655 namelen, oldp, oldlenp, newp, newlen)); 656 } 657 /* NOTREACHED */ 658 } 659 660 /* 661 * hardware related system variables. 662 */ 663 char *hw_vendor, *hw_prod, *hw_uuid, *hw_serial, *hw_ver; 664 int allowpowerdown = 1; 665 int hw_power = 1; 666 667 /* morally const values reported by sysctl_bounded_arr */ 668 static int byte_order = BYTE_ORDER; 669 670 const struct sysctl_bounded_args hw_vars[] = { 671 {HW_NCPU, &ncpus, SYSCTL_INT_READONLY}, 672 {HW_NCPUFOUND, &ncpusfound, SYSCTL_INT_READONLY}, 673 {HW_BYTEORDER, &byte_order, SYSCTL_INT_READONLY}, 674 {HW_PAGESIZE, &uvmexp.pagesize, SYSCTL_INT_READONLY}, 675 {HW_DISKCOUNT, &disk_count, SYSCTL_INT_READONLY}, 676 {HW_POWER, &hw_power, SYSCTL_INT_READONLY}, 677 }; 678 679 int 680 hw_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, 681 size_t newlen, struct proc *p) 682 { 683 extern char machine[], cpu_model[]; 684 int err, cpuspeed; 685 686 /* 687 * all sysctl names at this level except sensors and battery 688 * are terminal 689 */ 690 if (name[0] != HW_SENSORS && name[0] != HW_BATTERY && namelen != 1) 691 return (ENOTDIR); /* overloaded */ 692 693 switch (name[0]) { 694 case HW_MACHINE: 695 return (sysctl_rdstring(oldp, oldlenp, newp, machine)); 696 case HW_MODEL: 697 return (sysctl_rdstring(oldp, oldlenp, newp, cpu_model)); 698 case HW_NCPUONLINE: 699 return (sysctl_rdint(oldp, oldlenp, newp, 700 sysctl_hwncpuonline())); 701 case HW_PHYSMEM: 702 return (sysctl_rdint(oldp, oldlenp, newp, ptoa(physmem))); 703 case HW_USERMEM: 704 return (sysctl_rdint(oldp, oldlenp, newp, 705 ptoa(physmem - uvmexp.wired))); 706 case HW_DISKNAMES: 707 err = sysctl_diskinit(0, p); 708 if (err) 709 return err; 710 if (disknames) 711 return (sysctl_rdstring(oldp, oldlenp, newp, 712 disknames)); 713 else 714 return (sysctl_rdstring(oldp, oldlenp, newp, "")); 715 case HW_DISKSTATS: 716 err = sysctl_diskinit(1, p); 717 if (err) 718 return err; 719 return (sysctl_rdstruct(oldp, oldlenp, newp, diskstats, 720 disk_count * sizeof(struct diskstats))); 721 case HW_CPUSPEED: 722 if (!cpu_cpuspeed) 723 return (EOPNOTSUPP); 724 err = cpu_cpuspeed(&cpuspeed); 725 if (err) 726 return err; 727 return (sysctl_rdint(oldp, oldlenp, newp, cpuspeed)); 728 #ifndef SMALL_KERNEL 729 case HW_SENSORS: 730 return (sysctl_sensors(name + 1, namelen - 1, oldp, oldlenp, 731 newp, newlen)); 732 case HW_SETPERF: 733 return (sysctl_hwsetperf(oldp, oldlenp, newp, newlen)); 734 case HW_PERFPOLICY: 735 return (sysctl_hwperfpolicy(oldp, oldlenp, newp, newlen)); 736 #endif /* !SMALL_KERNEL */ 737 case HW_VENDOR: 738 if (hw_vendor) 739 return (sysctl_rdstring(oldp, oldlenp, newp, 740 hw_vendor)); 741 else 742 return (EOPNOTSUPP); 743 case HW_PRODUCT: 744 if (hw_prod) 745 return (sysctl_rdstring(oldp, oldlenp, newp, hw_prod)); 746 else 747 return (EOPNOTSUPP); 748 case HW_VERSION: 749 if (hw_ver) 750 return (sysctl_rdstring(oldp, oldlenp, newp, hw_ver)); 751 else 752 return (EOPNOTSUPP); 753 case HW_SERIALNO: 754 if (hw_serial) 755 return (sysctl_rdstring(oldp, oldlenp, newp, 756 hw_serial)); 757 else 758 return (EOPNOTSUPP); 759 case HW_UUID: 760 if (hw_uuid) 761 return (sysctl_rdstring(oldp, oldlenp, newp, hw_uuid)); 762 else 763 return (EOPNOTSUPP); 764 case HW_PHYSMEM64: 765 return (sysctl_rdquad(oldp, oldlenp, newp, 766 ptoa((psize_t)physmem))); 767 case HW_USERMEM64: 768 return (sysctl_rdquad(oldp, oldlenp, newp, 769 ptoa((psize_t)physmem - uvmexp.wired))); 770 case HW_ALLOWPOWERDOWN: 771 return (sysctl_securelevel_int(oldp, oldlenp, newp, newlen, 772 &allowpowerdown)); 773 case HW_UCOMNAMES: { 774 const char *str = ""; 775 #if NUCOM > 0 776 str = sysctl_ucominit(); 777 #endif /* NUCOM > 0 */ 778 return (sysctl_rdstring(oldp, oldlenp, newp, str)); 779 } 780 #ifdef __HAVE_CPU_TOPOLOGY 781 case HW_SMT: 782 return (sysctl_hwsmt(oldp, oldlenp, newp, newlen)); 783 #endif 784 #ifndef SMALL_KERNEL 785 case HW_BATTERY: 786 return (sysctl_hwbattery(name + 1, namelen - 1, oldp, oldlenp, 787 newp, newlen)); 788 #endif 789 default: 790 return sysctl_bounded_arr(hw_vars, nitems(hw_vars), name, 791 namelen, oldp, oldlenp, newp, newlen); 792 } 793 /* NOTREACHED */ 794 } 795 796 #ifndef SMALL_KERNEL 797 798 int hw_battery_chargemode; 799 int hw_battery_chargestart; 800 int hw_battery_chargestop; 801 int (*hw_battery_setchargemode)(int); 802 int (*hw_battery_setchargestart)(int); 803 int (*hw_battery_setchargestop)(int); 804 805 int 806 sysctl_hwchargemode(void *oldp, size_t *oldlenp, void *newp, size_t newlen) 807 { 808 int mode = hw_battery_chargemode; 809 int error; 810 811 if (!hw_battery_setchargemode) 812 return EOPNOTSUPP; 813 814 error = sysctl_int_bounded(oldp, oldlenp, newp, newlen, 815 &mode, -1, 1); 816 if (error) 817 return error; 818 819 if (newp != NULL) 820 error = hw_battery_setchargemode(mode); 821 822 return error; 823 } 824 825 int 826 sysctl_hwchargestart(void *oldp, size_t *oldlenp, void *newp, size_t newlen) 827 { 828 int start = hw_battery_chargestart; 829 int error; 830 831 if (!hw_battery_setchargestart) 832 return EOPNOTSUPP; 833 834 error = sysctl_int_bounded(oldp, oldlenp, newp, newlen, 835 &start, 0, 100); 836 if (error) 837 return error; 838 839 if (newp != NULL) 840 error = hw_battery_setchargestart(start); 841 842 return error; 843 } 844 845 int 846 sysctl_hwchargestop(void *oldp, size_t *oldlenp, void *newp, size_t newlen) 847 { 848 int stop = hw_battery_chargestop; 849 int error; 850 851 if (!hw_battery_setchargestop) 852 return EOPNOTSUPP; 853 854 error = sysctl_int_bounded(oldp, oldlenp, newp, newlen, 855 &stop, 0, 100); 856 if (error) 857 return error; 858 859 if (newp != NULL) 860 error = hw_battery_setchargestop(stop); 861 862 return error; 863 } 864 865 int 866 sysctl_hwbattery(int *name, u_int namelen, void *oldp, size_t *oldlenp, 867 void *newp, size_t newlen) 868 { 869 if (namelen != 1) 870 return (ENOTDIR); 871 872 switch (name[0]) { 873 case HW_BATTERY_CHARGEMODE: 874 return (sysctl_hwchargemode(oldp, oldlenp, newp, newlen)); 875 case HW_BATTERY_CHARGESTART: 876 return (sysctl_hwchargestart(oldp, oldlenp, newp, newlen)); 877 case HW_BATTERY_CHARGESTOP: 878 return (sysctl_hwchargestop(oldp, oldlenp, newp, newlen)); 879 default: 880 return (EOPNOTSUPP); 881 } 882 /* NOTREACHED */ 883 } 884 885 #endif 886 887 #ifdef DEBUG_SYSCTL 888 /* 889 * Debugging related system variables. 890 */ 891 extern struct ctldebug debug_vfs_busyprt; 892 struct ctldebug debug1, debug2, debug3, debug4; 893 struct ctldebug debug5, debug6, debug7, debug8, debug9; 894 struct ctldebug debug10, debug11, debug12, debug13, debug14; 895 struct ctldebug debug15, debug16, debug17, debug18, debug19; 896 static struct ctldebug *debugvars[CTL_DEBUG_MAXID] = { 897 &debug_vfs_busyprt, 898 &debug1, &debug2, &debug3, &debug4, 899 &debug5, &debug6, &debug7, &debug8, &debug9, 900 &debug10, &debug11, &debug12, &debug13, &debug14, 901 &debug15, &debug16, &debug17, &debug18, &debug19, 902 }; 903 int 904 debug_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, 905 size_t newlen, struct proc *p) 906 { 907 struct ctldebug *cdp; 908 909 /* all sysctl names at this level are name and field */ 910 if (namelen != 2) 911 return (ENOTDIR); /* overloaded */ 912 if (name[0] < 0 || name[0] >= nitems(debugvars)) 913 return (EOPNOTSUPP); 914 cdp = debugvars[name[0]]; 915 if (cdp->debugname == 0) 916 return (EOPNOTSUPP); 917 switch (name[1]) { 918 case CTL_DEBUG_NAME: 919 return (sysctl_rdstring(oldp, oldlenp, newp, cdp->debugname)); 920 case CTL_DEBUG_VALUE: 921 return (sysctl_int(oldp, oldlenp, newp, newlen, cdp->debugvar)); 922 default: 923 return (EOPNOTSUPP); 924 } 925 /* NOTREACHED */ 926 } 927 #endif /* DEBUG_SYSCTL */ 928 929 /* 930 * Reads, or writes that lower the value 931 */ 932 int 933 sysctl_int_lower(void *oldp, size_t *oldlenp, void *newp, size_t newlen, 934 int *valp) 935 { 936 unsigned int oval = *valp, val = *valp; 937 int error; 938 939 if (newp == NULL) 940 return (sysctl_rdint(oldp, oldlenp, newp, val)); 941 942 if ((error = sysctl_int(oldp, oldlenp, newp, newlen, &val))) 943 return (error); 944 if (val > oval) 945 return (EPERM); /* do not allow raising */ 946 *(unsigned int *)valp = val; 947 return (0); 948 } 949 950 /* 951 * Validate parameters and get old / set new parameters 952 * for an integer-valued sysctl function. 953 */ 954 int 955 sysctl_int(void *oldp, size_t *oldlenp, void *newp, size_t newlen, int *valp) 956 { 957 int error = 0; 958 959 if (oldp && *oldlenp < sizeof(int)) 960 return (ENOMEM); 961 if (newp && newlen != sizeof(int)) 962 return (EINVAL); 963 *oldlenp = sizeof(int); 964 if (oldp) 965 error = copyout(valp, oldp, sizeof(int)); 966 if (error == 0 && newp) 967 error = copyin(newp, valp, sizeof(int)); 968 return (error); 969 } 970 971 /* 972 * As above, but read-only. 973 */ 974 int 975 sysctl_rdint(void *oldp, size_t *oldlenp, void *newp, int val) 976 { 977 int error = 0; 978 979 if (oldp && *oldlenp < sizeof(int)) 980 return (ENOMEM); 981 if (newp) 982 return (EPERM); 983 *oldlenp = sizeof(int); 984 if (oldp) 985 error = copyout((caddr_t)&val, oldp, sizeof(int)); 986 return (error); 987 } 988 989 /* 990 * Selects between sysctl_rdint and sysctl_int according to securelevel. 991 */ 992 int 993 sysctl_securelevel_int(void *oldp, size_t *oldlenp, void *newp, size_t newlen, 994 int *valp) 995 { 996 if (securelevel > 0) 997 return (sysctl_rdint(oldp, oldlenp, newp, *valp)); 998 return (sysctl_int(oldp, oldlenp, newp, newlen, valp)); 999 } 1000 1001 /* 1002 * Read-only or bounded integer values. 1003 */ 1004 int 1005 sysctl_int_bounded(void *oldp, size_t *oldlenp, void *newp, size_t newlen, 1006 int *valp, int minimum, int maximum) 1007 { 1008 int val = *valp; 1009 int error; 1010 1011 /* read only */ 1012 if (newp == NULL || minimum > maximum) 1013 return (sysctl_rdint(oldp, oldlenp, newp, val)); 1014 1015 if ((error = sysctl_int(oldp, oldlenp, newp, newlen, &val))) 1016 return (error); 1017 /* outside limits */ 1018 if (val < minimum || maximum < val) 1019 return (EINVAL); 1020 *valp = val; 1021 return (0); 1022 } 1023 1024 /* 1025 * Array of read-only or bounded integer values. 1026 */ 1027 int 1028 sysctl_bounded_arr(const struct sysctl_bounded_args *valpp, u_int valplen, 1029 int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, 1030 size_t newlen) 1031 { 1032 u_int i; 1033 if (namelen != 1) 1034 return (ENOTDIR); 1035 for (i = 0; i < valplen; ++i) { 1036 if (valpp[i].mib == name[0]) { 1037 return (sysctl_int_bounded(oldp, oldlenp, newp, newlen, 1038 valpp[i].var, valpp[i].minimum, valpp[i].maximum)); 1039 } 1040 } 1041 return (EOPNOTSUPP); 1042 } 1043 1044 /* 1045 * Validate parameters and get old / set new parameters 1046 * for an integer-valued sysctl function. 1047 */ 1048 int 1049 sysctl_quad(void *oldp, size_t *oldlenp, void *newp, size_t newlen, 1050 int64_t *valp) 1051 { 1052 int error = 0; 1053 1054 if (oldp && *oldlenp < sizeof(int64_t)) 1055 return (ENOMEM); 1056 if (newp && newlen != sizeof(int64_t)) 1057 return (EINVAL); 1058 *oldlenp = sizeof(int64_t); 1059 if (oldp) 1060 error = copyout(valp, oldp, sizeof(int64_t)); 1061 if (error == 0 && newp) 1062 error = copyin(newp, valp, sizeof(int64_t)); 1063 return (error); 1064 } 1065 1066 /* 1067 * As above, but read-only. 1068 */ 1069 int 1070 sysctl_rdquad(void *oldp, size_t *oldlenp, void *newp, int64_t val) 1071 { 1072 int error = 0; 1073 1074 if (oldp && *oldlenp < sizeof(int64_t)) 1075 return (ENOMEM); 1076 if (newp) 1077 return (EPERM); 1078 *oldlenp = sizeof(int64_t); 1079 if (oldp) 1080 error = copyout((caddr_t)&val, oldp, sizeof(int64_t)); 1081 return (error); 1082 } 1083 1084 /* 1085 * Validate parameters and get old / set new parameters 1086 * for a string-valued sysctl function. 1087 */ 1088 int 1089 sysctl_string(void *oldp, size_t *oldlenp, void *newp, size_t newlen, char *str, 1090 size_t maxlen) 1091 { 1092 return sysctl__string(oldp, oldlenp, newp, newlen, str, maxlen, 0); 1093 } 1094 1095 int 1096 sysctl_tstring(void *oldp, size_t *oldlenp, void *newp, size_t newlen, 1097 char *str, size_t maxlen) 1098 { 1099 return sysctl__string(oldp, oldlenp, newp, newlen, str, maxlen, 1); 1100 } 1101 1102 int 1103 sysctl__string(void *oldp, size_t *oldlenp, void *newp, size_t newlen, 1104 char *str, size_t maxlen, int trunc) 1105 { 1106 size_t len; 1107 int error = 0; 1108 1109 len = strlen(str) + 1; 1110 if (oldp && *oldlenp < len) { 1111 if (trunc == 0 || *oldlenp == 0) 1112 return (ENOMEM); 1113 } 1114 if (newp && newlen >= maxlen) 1115 return (EINVAL); 1116 if (oldp) { 1117 if (trunc && *oldlenp < len) { 1118 len = *oldlenp; 1119 error = copyout(str, oldp, len - 1); 1120 if (error == 0) 1121 error = copyout("", (char *)oldp + len - 1, 1); 1122 } else { 1123 error = copyout(str, oldp, len); 1124 } 1125 } 1126 *oldlenp = len; 1127 if (error == 0 && newp) { 1128 error = copyin(newp, str, newlen); 1129 str[newlen] = 0; 1130 } 1131 return (error); 1132 } 1133 1134 /* 1135 * As above, but read-only. 1136 */ 1137 int 1138 sysctl_rdstring(void *oldp, size_t *oldlenp, void *newp, const char *str) 1139 { 1140 size_t len; 1141 int error = 0; 1142 1143 len = strlen(str) + 1; 1144 if (oldp && *oldlenp < len) 1145 return (ENOMEM); 1146 if (newp) 1147 return (EPERM); 1148 *oldlenp = len; 1149 if (oldp) 1150 error = copyout(str, oldp, len); 1151 return (error); 1152 } 1153 1154 /* 1155 * Validate parameters and get old / set new parameters 1156 * for a structure oriented sysctl function. 1157 */ 1158 int 1159 sysctl_struct(void *oldp, size_t *oldlenp, void *newp, size_t newlen, void *sp, 1160 size_t len) 1161 { 1162 int error = 0; 1163 1164 if (oldp && *oldlenp < len) 1165 return (ENOMEM); 1166 if (newp && newlen > len) 1167 return (EINVAL); 1168 if (oldp) { 1169 *oldlenp = len; 1170 error = copyout(sp, oldp, len); 1171 } 1172 if (error == 0 && newp) 1173 error = copyin(newp, sp, len); 1174 return (error); 1175 } 1176 1177 /* 1178 * Validate parameters and get old parameters 1179 * for a structure oriented sysctl function. 1180 */ 1181 int 1182 sysctl_rdstruct(void *oldp, size_t *oldlenp, void *newp, const void *sp, 1183 size_t len) 1184 { 1185 int error = 0; 1186 1187 if (oldp && *oldlenp < len) 1188 return (ENOMEM); 1189 if (newp) 1190 return (EPERM); 1191 *oldlenp = len; 1192 if (oldp) 1193 error = copyout(sp, oldp, len); 1194 return (error); 1195 } 1196 1197 #ifndef SMALL_KERNEL 1198 void 1199 fill_file(struct kinfo_file *kf, struct file *fp, struct filedesc *fdp, 1200 int fd, struct vnode *vp, struct process *pr, struct proc *p, 1201 struct socket *so, int show_pointers) 1202 { 1203 struct vattr va; 1204 1205 memset(kf, 0, sizeof(*kf)); 1206 1207 kf->fd_fd = fd; /* might not really be an fd */ 1208 1209 if (fp != NULL) { 1210 if (show_pointers) 1211 kf->f_fileaddr = PTRTOINT64(fp); 1212 kf->f_flag = fp->f_flag; 1213 kf->f_iflags = fp->f_iflags; 1214 kf->f_type = fp->f_type; 1215 kf->f_count = fp->f_count; 1216 if (show_pointers) 1217 kf->f_ucred = PTRTOINT64(fp->f_cred); 1218 kf->f_uid = fp->f_cred->cr_uid; 1219 kf->f_gid = fp->f_cred->cr_gid; 1220 if (show_pointers) 1221 kf->f_ops = PTRTOINT64(fp->f_ops); 1222 if (show_pointers) 1223 kf->f_data = PTRTOINT64(fp->f_data); 1224 kf->f_usecount = 0; 1225 1226 if (suser(p) == 0 || p->p_ucred->cr_uid == fp->f_cred->cr_uid) { 1227 mtx_enter(&fp->f_mtx); 1228 kf->f_offset = fp->f_offset; 1229 kf->f_rxfer = fp->f_rxfer; 1230 kf->f_rwfer = fp->f_wxfer; 1231 kf->f_seek = fp->f_seek; 1232 kf->f_rbytes = fp->f_rbytes; 1233 kf->f_wbytes = fp->f_wbytes; 1234 mtx_leave(&fp->f_mtx); 1235 } else 1236 kf->f_offset = -1; 1237 } else if (vp != NULL) { 1238 /* fake it */ 1239 kf->f_type = DTYPE_VNODE; 1240 kf->f_flag = FREAD; 1241 if (fd == KERN_FILE_TRACE) 1242 kf->f_flag |= FWRITE; 1243 } else if (so != NULL) { 1244 /* fake it */ 1245 kf->f_type = DTYPE_SOCKET; 1246 } 1247 1248 /* information about the object associated with this file */ 1249 switch (kf->f_type) { 1250 case DTYPE_VNODE: 1251 if (fp != NULL) 1252 vp = (struct vnode *)fp->f_data; 1253 1254 if (show_pointers) 1255 kf->v_un = PTRTOINT64(vp->v_un.vu_socket); 1256 kf->v_type = vp->v_type; 1257 kf->v_tag = vp->v_tag; 1258 kf->v_flag = vp->v_flag; 1259 if (show_pointers) 1260 kf->v_data = PTRTOINT64(vp->v_data); 1261 if (show_pointers) 1262 kf->v_mount = PTRTOINT64(vp->v_mount); 1263 if (vp->v_mount) 1264 strlcpy(kf->f_mntonname, 1265 vp->v_mount->mnt_stat.f_mntonname, 1266 sizeof(kf->f_mntonname)); 1267 1268 if (VOP_GETATTR(vp, &va, p->p_ucred, p) == 0) { 1269 kf->va_fileid = va.va_fileid; 1270 kf->va_mode = MAKEIMODE(va.va_type, va.va_mode); 1271 kf->va_size = va.va_size; 1272 kf->va_rdev = va.va_rdev; 1273 kf->va_fsid = va.va_fsid & 0xffffffff; 1274 kf->va_nlink = va.va_nlink; 1275 } 1276 break; 1277 1278 case DTYPE_SOCKET: { 1279 int locked = 0; 1280 1281 if (so == NULL) { 1282 so = (struct socket *)fp->f_data; 1283 /* if so is passed as parameter it is already locked */ 1284 solock(so); 1285 locked = 1; 1286 } 1287 1288 kf->so_type = so->so_type; 1289 kf->so_state = so->so_state | so->so_snd.sb_state | 1290 so->so_rcv.sb_state; 1291 if (show_pointers) 1292 kf->so_pcb = PTRTOINT64(so->so_pcb); 1293 else 1294 kf->so_pcb = -1; 1295 kf->so_protocol = so->so_proto->pr_protocol; 1296 kf->so_family = so->so_proto->pr_domain->dom_family; 1297 kf->so_rcv_cc = so->so_rcv.sb_cc; 1298 kf->so_snd_cc = so->so_snd.sb_cc; 1299 if (isspliced(so)) { 1300 if (show_pointers) 1301 kf->so_splice = 1302 PTRTOINT64(so->so_sp->ssp_socket); 1303 kf->so_splicelen = so->so_sp->ssp_len; 1304 } else if (issplicedback(so)) 1305 kf->so_splicelen = -1; 1306 if (so->so_pcb == NULL) { 1307 if (locked) 1308 sounlock(so); 1309 break; 1310 } 1311 switch (kf->so_family) { 1312 case AF_INET: { 1313 struct inpcb *inpcb = so->so_pcb; 1314 1315 soassertlocked(so); 1316 if (show_pointers) 1317 kf->inp_ppcb = PTRTOINT64(inpcb->inp_ppcb); 1318 kf->inp_lport = inpcb->inp_lport; 1319 kf->inp_laddru[0] = inpcb->inp_laddr.s_addr; 1320 kf->inp_fport = inpcb->inp_fport; 1321 kf->inp_faddru[0] = inpcb->inp_faddr.s_addr; 1322 kf->inp_rtableid = inpcb->inp_rtableid; 1323 if (so->so_type == SOCK_RAW) 1324 kf->inp_proto = inpcb->inp_ip.ip_p; 1325 if (so->so_proto->pr_protocol == IPPROTO_TCP) { 1326 struct tcpcb *tcpcb = (void *)inpcb->inp_ppcb; 1327 kf->t_rcv_wnd = tcpcb->rcv_wnd; 1328 kf->t_snd_wnd = tcpcb->snd_wnd; 1329 kf->t_snd_cwnd = tcpcb->snd_cwnd; 1330 kf->t_state = tcpcb->t_state; 1331 } 1332 break; 1333 } 1334 case AF_INET6: { 1335 struct inpcb *inpcb = so->so_pcb; 1336 1337 soassertlocked(so); 1338 if (show_pointers) 1339 kf->inp_ppcb = PTRTOINT64(inpcb->inp_ppcb); 1340 kf->inp_lport = inpcb->inp_lport; 1341 kf->inp_laddru[0] = inpcb->inp_laddr6.s6_addr32[0]; 1342 kf->inp_laddru[1] = inpcb->inp_laddr6.s6_addr32[1]; 1343 kf->inp_laddru[2] = inpcb->inp_laddr6.s6_addr32[2]; 1344 kf->inp_laddru[3] = inpcb->inp_laddr6.s6_addr32[3]; 1345 kf->inp_fport = inpcb->inp_fport; 1346 kf->inp_faddru[0] = inpcb->inp_faddr6.s6_addr32[0]; 1347 kf->inp_faddru[1] = inpcb->inp_faddr6.s6_addr32[1]; 1348 kf->inp_faddru[2] = inpcb->inp_faddr6.s6_addr32[2]; 1349 kf->inp_faddru[3] = inpcb->inp_faddr6.s6_addr32[3]; 1350 kf->inp_rtableid = inpcb->inp_rtableid; 1351 if (so->so_type == SOCK_RAW) 1352 kf->inp_proto = inpcb->inp_ipv6.ip6_nxt; 1353 if (so->so_proto->pr_protocol == IPPROTO_TCP) { 1354 struct tcpcb *tcpcb = (void *)inpcb->inp_ppcb; 1355 kf->t_rcv_wnd = tcpcb->rcv_wnd; 1356 kf->t_snd_wnd = tcpcb->snd_wnd; 1357 kf->t_state = tcpcb->t_state; 1358 } 1359 break; 1360 } 1361 case AF_UNIX: { 1362 struct unpcb *unpcb = so->so_pcb; 1363 1364 kf->f_msgcount = unpcb->unp_msgcount; 1365 if (show_pointers) { 1366 kf->unp_conn = PTRTOINT64(unpcb->unp_conn); 1367 kf->unp_refs = PTRTOINT64( 1368 SLIST_FIRST(&unpcb->unp_refs)); 1369 kf->unp_nextref = PTRTOINT64( 1370 SLIST_NEXT(unpcb, unp_nextref)); 1371 kf->v_un = PTRTOINT64(unpcb->unp_vnode); 1372 kf->unp_addr = PTRTOINT64(unpcb->unp_addr); 1373 } 1374 if (unpcb->unp_addr != NULL) { 1375 struct sockaddr_un *un = mtod(unpcb->unp_addr, 1376 struct sockaddr_un *); 1377 memcpy(kf->unp_path, un->sun_path, un->sun_len 1378 - offsetof(struct sockaddr_un,sun_path)); 1379 } 1380 break; 1381 } 1382 } 1383 if (locked) 1384 sounlock(so); 1385 break; 1386 } 1387 1388 case DTYPE_PIPE: { 1389 struct pipe *pipe = (struct pipe *)fp->f_data; 1390 1391 if (show_pointers) 1392 kf->pipe_peer = PTRTOINT64(pipe->pipe_peer); 1393 kf->pipe_state = pipe->pipe_state; 1394 break; 1395 } 1396 1397 case DTYPE_KQUEUE: { 1398 struct kqueue *kqi = (struct kqueue *)fp->f_data; 1399 1400 kf->kq_count = kqi->kq_count; 1401 kf->kq_state = kqi->kq_state; 1402 break; 1403 } 1404 } 1405 1406 /* per-process information for KERN_FILE_BY[PU]ID */ 1407 if (pr != NULL) { 1408 kf->p_pid = pr->ps_pid; 1409 kf->p_uid = pr->ps_ucred->cr_uid; 1410 kf->p_gid = pr->ps_ucred->cr_gid; 1411 kf->p_tid = -1; 1412 strlcpy(kf->p_comm, pr->ps_comm, sizeof(kf->p_comm)); 1413 } 1414 if (fdp != NULL) { 1415 fdplock(fdp); 1416 kf->fd_ofileflags = fdp->fd_ofileflags[fd]; 1417 fdpunlock(fdp); 1418 } 1419 } 1420 1421 /* 1422 * Get file structures. 1423 */ 1424 int 1425 sysctl_file(int *name, u_int namelen, char *where, size_t *sizep, 1426 struct proc *p) 1427 { 1428 struct kinfo_file *kf; 1429 struct filedesc *fdp; 1430 struct file *fp; 1431 struct process *pr; 1432 size_t buflen, elem_size, elem_count, outsize; 1433 char *dp = where; 1434 int arg, i, error = 0, needed = 0, matched; 1435 u_int op; 1436 int show_pointers; 1437 1438 if (namelen > 4) 1439 return (ENOTDIR); 1440 if (namelen < 4 || name[2] > sizeof(*kf)) 1441 return (EINVAL); 1442 1443 buflen = where != NULL ? *sizep : 0; 1444 op = name[0]; 1445 arg = name[1]; 1446 elem_size = name[2]; 1447 elem_count = name[3]; 1448 outsize = MIN(sizeof(*kf), elem_size); 1449 1450 if (elem_size < 1) 1451 return (EINVAL); 1452 1453 show_pointers = suser(curproc) == 0; 1454 1455 kf = malloc(sizeof(*kf), M_TEMP, M_WAITOK); 1456 1457 #define FILLIT2(fp, fdp, i, vp, pr, so) do { \ 1458 if (buflen >= elem_size && elem_count > 0) { \ 1459 fill_file(kf, fp, fdp, i, vp, pr, p, so, show_pointers);\ 1460 error = copyout(kf, dp, outsize); \ 1461 if (error) \ 1462 break; \ 1463 dp += elem_size; \ 1464 buflen -= elem_size; \ 1465 elem_count--; \ 1466 } \ 1467 needed += elem_size; \ 1468 } while (0) 1469 #define FILLIT(fp, fdp, i, vp, pr) \ 1470 FILLIT2(fp, fdp, i, vp, pr, NULL) 1471 #define FILLSO(so) \ 1472 FILLIT2(NULL, NULL, 0, NULL, NULL, so) 1473 1474 switch (op) { 1475 case KERN_FILE_BYFILE: 1476 /* use the inp-tables to pick up closed connections, too */ 1477 if (arg == DTYPE_SOCKET) { 1478 struct inpcb *inp; 1479 1480 NET_LOCK(); 1481 mtx_enter(&tcbtable.inpt_mtx); 1482 TAILQ_FOREACH(inp, &tcbtable.inpt_queue, inp_queue) 1483 FILLSO(inp->inp_socket); 1484 mtx_leave(&tcbtable.inpt_mtx); 1485 #ifdef INET6 1486 mtx_enter(&tcb6table.inpt_mtx); 1487 TAILQ_FOREACH(inp, &tcb6table.inpt_queue, inp_queue) 1488 FILLSO(inp->inp_socket); 1489 mtx_leave(&tcb6table.inpt_mtx); 1490 #endif 1491 mtx_enter(&udbtable.inpt_mtx); 1492 TAILQ_FOREACH(inp, &udbtable.inpt_queue, inp_queue) 1493 FILLSO(inp->inp_socket); 1494 mtx_leave(&udbtable.inpt_mtx); 1495 #ifdef INET6 1496 mtx_enter(&udb6table.inpt_mtx); 1497 TAILQ_FOREACH(inp, &udb6table.inpt_queue, inp_queue) 1498 FILLSO(inp->inp_socket); 1499 mtx_leave(&udb6table.inpt_mtx); 1500 #endif 1501 mtx_enter(&rawcbtable.inpt_mtx); 1502 TAILQ_FOREACH(inp, &rawcbtable.inpt_queue, inp_queue) 1503 FILLSO(inp->inp_socket); 1504 mtx_leave(&rawcbtable.inpt_mtx); 1505 #ifdef INET6 1506 mtx_enter(&rawin6pcbtable.inpt_mtx); 1507 TAILQ_FOREACH(inp, &rawin6pcbtable.inpt_queue, 1508 inp_queue) 1509 FILLSO(inp->inp_socket); 1510 mtx_leave(&rawin6pcbtable.inpt_mtx); 1511 #endif 1512 NET_UNLOCK(); 1513 } 1514 fp = NULL; 1515 while ((fp = fd_iterfile(fp, p)) != NULL) { 1516 if ((arg == 0 || fp->f_type == arg)) { 1517 int af, skip = 0; 1518 if (arg == DTYPE_SOCKET && fp->f_type == arg) { 1519 af = ((struct socket *)fp->f_data)-> 1520 so_proto->pr_domain->dom_family; 1521 if (af == AF_INET || af == AF_INET6) 1522 skip = 1; 1523 } 1524 if (!skip) 1525 FILLIT(fp, NULL, 0, NULL, NULL); 1526 } 1527 } 1528 break; 1529 case KERN_FILE_BYPID: 1530 /* A arg of -1 indicates all processes */ 1531 if (arg < -1) { 1532 error = EINVAL; 1533 break; 1534 } 1535 matched = 0; 1536 LIST_FOREACH(pr, &allprocess, ps_list) { 1537 /* 1538 * skip system, exiting, embryonic and undead 1539 * processes 1540 */ 1541 if (pr->ps_flags & (PS_SYSTEM | PS_EMBRYO | PS_EXITING)) 1542 continue; 1543 if (arg > 0 && pr->ps_pid != (pid_t)arg) { 1544 /* not the pid we are looking for */ 1545 continue; 1546 } 1547 matched = 1; 1548 fdp = pr->ps_fd; 1549 if (pr->ps_textvp) 1550 FILLIT(NULL, NULL, KERN_FILE_TEXT, pr->ps_textvp, pr); 1551 if (fdp->fd_cdir) 1552 FILLIT(NULL, NULL, KERN_FILE_CDIR, fdp->fd_cdir, pr); 1553 if (fdp->fd_rdir) 1554 FILLIT(NULL, NULL, KERN_FILE_RDIR, fdp->fd_rdir, pr); 1555 if (pr->ps_tracevp) 1556 FILLIT(NULL, NULL, KERN_FILE_TRACE, pr->ps_tracevp, pr); 1557 for (i = 0; i < fdp->fd_nfiles; i++) { 1558 if ((fp = fd_getfile(fdp, i)) == NULL) 1559 continue; 1560 FILLIT(fp, fdp, i, NULL, pr); 1561 FRELE(fp, p); 1562 } 1563 } 1564 if (!matched) 1565 error = ESRCH; 1566 break; 1567 case KERN_FILE_BYUID: 1568 LIST_FOREACH(pr, &allprocess, ps_list) { 1569 /* 1570 * skip system, exiting, embryonic and undead 1571 * processes 1572 */ 1573 if (pr->ps_flags & (PS_SYSTEM | PS_EMBRYO | PS_EXITING)) 1574 continue; 1575 if (arg >= 0 && pr->ps_ucred->cr_uid != (uid_t)arg) { 1576 /* not the uid we are looking for */ 1577 continue; 1578 } 1579 fdp = pr->ps_fd; 1580 if (fdp->fd_cdir) 1581 FILLIT(NULL, NULL, KERN_FILE_CDIR, fdp->fd_cdir, pr); 1582 if (fdp->fd_rdir) 1583 FILLIT(NULL, NULL, KERN_FILE_RDIR, fdp->fd_rdir, pr); 1584 if (pr->ps_tracevp) 1585 FILLIT(NULL, NULL, KERN_FILE_TRACE, pr->ps_tracevp, pr); 1586 for (i = 0; i < fdp->fd_nfiles; i++) { 1587 if ((fp = fd_getfile(fdp, i)) == NULL) 1588 continue; 1589 FILLIT(fp, fdp, i, NULL, pr); 1590 FRELE(fp, p); 1591 } 1592 } 1593 break; 1594 default: 1595 error = EINVAL; 1596 break; 1597 } 1598 free(kf, M_TEMP, sizeof(*kf)); 1599 1600 if (!error) { 1601 if (where == NULL) 1602 needed += KERN_FILESLOP * elem_size; 1603 else if (*sizep < needed) 1604 error = ENOMEM; 1605 *sizep = needed; 1606 } 1607 1608 return (error); 1609 } 1610 1611 /* 1612 * try over estimating by 5 procs 1613 */ 1614 #define KERN_PROCSLOP 5 1615 1616 int 1617 sysctl_doproc(int *name, u_int namelen, char *where, size_t *sizep) 1618 { 1619 struct kinfo_proc *kproc = NULL; 1620 struct proc *p; 1621 struct process *pr; 1622 char *dp; 1623 int arg, buflen, doingzomb, elem_size, elem_count; 1624 int error, needed, op; 1625 int dothreads = 0; 1626 int show_pointers; 1627 1628 dp = where; 1629 buflen = where != NULL ? *sizep : 0; 1630 needed = error = 0; 1631 1632 if (namelen != 4 || name[2] <= 0 || name[3] < 0 || 1633 name[2] > sizeof(*kproc)) 1634 return (EINVAL); 1635 op = name[0]; 1636 arg = name[1]; 1637 elem_size = name[2]; 1638 elem_count = name[3]; 1639 1640 dothreads = op & KERN_PROC_SHOW_THREADS; 1641 op &= ~KERN_PROC_SHOW_THREADS; 1642 1643 show_pointers = suser(curproc) == 0; 1644 1645 if (where != NULL) 1646 kproc = malloc(sizeof(*kproc), M_TEMP, M_WAITOK); 1647 1648 pr = LIST_FIRST(&allprocess); 1649 doingzomb = 0; 1650 again: 1651 for (; pr != NULL; pr = LIST_NEXT(pr, ps_list)) { 1652 /* XXX skip processes in the middle of being zapped */ 1653 if (pr->ps_pgrp == NULL) 1654 continue; 1655 1656 /* 1657 * Skip embryonic processes. 1658 */ 1659 if (pr->ps_flags & PS_EMBRYO) 1660 continue; 1661 1662 /* 1663 * TODO - make more efficient (see notes below). 1664 */ 1665 switch (op) { 1666 1667 case KERN_PROC_PID: 1668 /* could do this with just a lookup */ 1669 if (pr->ps_pid != (pid_t)arg) 1670 continue; 1671 break; 1672 1673 case KERN_PROC_PGRP: 1674 /* could do this by traversing pgrp */ 1675 if (pr->ps_pgrp->pg_id != (pid_t)arg) 1676 continue; 1677 break; 1678 1679 case KERN_PROC_SESSION: 1680 if (pr->ps_session->s_leader == NULL || 1681 pr->ps_session->s_leader->ps_pid != (pid_t)arg) 1682 continue; 1683 break; 1684 1685 case KERN_PROC_TTY: 1686 if ((pr->ps_flags & PS_CONTROLT) == 0 || 1687 pr->ps_session->s_ttyp == NULL || 1688 pr->ps_session->s_ttyp->t_dev != (dev_t)arg) 1689 continue; 1690 break; 1691 1692 case KERN_PROC_UID: 1693 if (pr->ps_ucred->cr_uid != (uid_t)arg) 1694 continue; 1695 break; 1696 1697 case KERN_PROC_RUID: 1698 if (pr->ps_ucred->cr_ruid != (uid_t)arg) 1699 continue; 1700 break; 1701 1702 case KERN_PROC_ALL: 1703 if (pr->ps_flags & PS_SYSTEM) 1704 continue; 1705 break; 1706 1707 case KERN_PROC_KTHREAD: 1708 /* no filtering */ 1709 break; 1710 1711 default: 1712 error = EINVAL; 1713 goto err; 1714 } 1715 1716 if (buflen >= elem_size && elem_count > 0) { 1717 fill_kproc(pr, kproc, NULL, show_pointers); 1718 error = copyout(kproc, dp, elem_size); 1719 if (error) 1720 goto err; 1721 dp += elem_size; 1722 buflen -= elem_size; 1723 elem_count--; 1724 } 1725 needed += elem_size; 1726 1727 /* Skip per-thread entries if not required by op */ 1728 if (!dothreads) 1729 continue; 1730 1731 TAILQ_FOREACH(p, &pr->ps_threads, p_thr_link) { 1732 if (buflen >= elem_size && elem_count > 0) { 1733 fill_kproc(pr, kproc, p, show_pointers); 1734 error = copyout(kproc, dp, elem_size); 1735 if (error) 1736 goto err; 1737 dp += elem_size; 1738 buflen -= elem_size; 1739 elem_count--; 1740 } 1741 needed += elem_size; 1742 } 1743 } 1744 if (doingzomb == 0) { 1745 pr = LIST_FIRST(&zombprocess); 1746 doingzomb++; 1747 goto again; 1748 } 1749 if (where != NULL) { 1750 *sizep = dp - where; 1751 if (needed > *sizep) { 1752 error = ENOMEM; 1753 goto err; 1754 } 1755 } else { 1756 needed += KERN_PROCSLOP * elem_size; 1757 *sizep = needed; 1758 } 1759 err: 1760 if (kproc) 1761 free(kproc, M_TEMP, sizeof(*kproc)); 1762 return (error); 1763 } 1764 1765 /* 1766 * Fill in a kproc structure for the specified process. 1767 */ 1768 void 1769 fill_kproc(struct process *pr, struct kinfo_proc *ki, struct proc *p, 1770 int show_pointers) 1771 { 1772 struct session *s = pr->ps_session; 1773 struct tty *tp; 1774 struct vmspace *vm = pr->ps_vmspace; 1775 struct timespec booted, st, ut, utc; 1776 int isthread; 1777 1778 isthread = p != NULL; 1779 if (!isthread) 1780 p = pr->ps_mainproc; /* XXX */ 1781 1782 FILL_KPROC(ki, strlcpy, p, pr, pr->ps_ucred, pr->ps_pgrp, 1783 p, pr, s, vm, pr->ps_limit, pr->ps_sigacts, isthread, 1784 show_pointers); 1785 1786 /* stuff that's too painful to generalize into the macros */ 1787 if (pr->ps_pptr) 1788 ki->p_ppid = pr->ps_ppid; 1789 if (s->s_leader) 1790 ki->p_sid = s->s_leader->ps_pid; 1791 1792 if ((pr->ps_flags & PS_CONTROLT) && (tp = s->s_ttyp)) { 1793 ki->p_tdev = tp->t_dev; 1794 ki->p_tpgid = tp->t_pgrp ? tp->t_pgrp->pg_id : -1; 1795 if (show_pointers) 1796 ki->p_tsess = PTRTOINT64(tp->t_session); 1797 } else { 1798 ki->p_tdev = NODEV; 1799 ki->p_tpgid = -1; 1800 } 1801 1802 /* fixups that can only be done in the kernel */ 1803 if ((pr->ps_flags & PS_ZOMBIE) == 0) { 1804 if ((pr->ps_flags & PS_EMBRYO) == 0 && vm != NULL) 1805 ki->p_vm_rssize = vm_resident_count(vm); 1806 calctsru(isthread ? &p->p_tu : &pr->ps_tu, &ut, &st, NULL); 1807 ki->p_uutime_sec = ut.tv_sec; 1808 ki->p_uutime_usec = ut.tv_nsec/1000; 1809 ki->p_ustime_sec = st.tv_sec; 1810 ki->p_ustime_usec = st.tv_nsec/1000; 1811 1812 /* Convert starting uptime to a starting UTC time. */ 1813 nanoboottime(&booted); 1814 timespecadd(&booted, &pr->ps_start, &utc); 1815 ki->p_ustart_sec = utc.tv_sec; 1816 ki->p_ustart_usec = utc.tv_nsec / 1000; 1817 1818 #ifdef MULTIPROCESSOR 1819 if (p->p_cpu != NULL) 1820 ki->p_cpuid = CPU_INFO_UNIT(p->p_cpu); 1821 #endif 1822 } 1823 1824 /* get %cpu and schedule state: just one thread or sum of all? */ 1825 if (isthread) { 1826 ki->p_pctcpu = p->p_pctcpu; 1827 ki->p_stat = p->p_stat; 1828 } else { 1829 ki->p_pctcpu = 0; 1830 ki->p_stat = (pr->ps_flags & PS_ZOMBIE) ? SDEAD : SIDL; 1831 TAILQ_FOREACH(p, &pr->ps_threads, p_thr_link) { 1832 ki->p_pctcpu += p->p_pctcpu; 1833 /* find best state: ONPROC > RUN > STOP > SLEEP > .. */ 1834 if (p->p_stat == SONPROC || ki->p_stat == SONPROC) 1835 ki->p_stat = SONPROC; 1836 else if (p->p_stat == SRUN || ki->p_stat == SRUN) 1837 ki->p_stat = SRUN; 1838 else if (p->p_stat == SSTOP || ki->p_stat == SSTOP) 1839 ki->p_stat = SSTOP; 1840 else if (p->p_stat == SSLEEP) 1841 ki->p_stat = SSLEEP; 1842 } 1843 } 1844 } 1845 1846 int 1847 sysctl_proc_args(int *name, u_int namelen, void *oldp, size_t *oldlenp, 1848 struct proc *cp) 1849 { 1850 struct process *vpr; 1851 pid_t pid; 1852 struct ps_strings pss; 1853 struct iovec iov; 1854 struct uio uio; 1855 int error, cnt, op; 1856 size_t limit; 1857 char **rargv, **vargv; /* reader vs. victim */ 1858 char *rarg, *varg, *buf; 1859 struct vmspace *vm; 1860 vaddr_t ps_strings; 1861 1862 if (namelen > 2) 1863 return (ENOTDIR); 1864 if (namelen < 2) 1865 return (EINVAL); 1866 1867 pid = name[0]; 1868 op = name[1]; 1869 1870 switch (op) { 1871 case KERN_PROC_ARGV: 1872 case KERN_PROC_NARGV: 1873 case KERN_PROC_ENV: 1874 case KERN_PROC_NENV: 1875 break; 1876 default: 1877 return (EOPNOTSUPP); 1878 } 1879 1880 if ((vpr = prfind(pid)) == NULL) 1881 return (ESRCH); 1882 1883 if (oldp == NULL) { 1884 if (op == KERN_PROC_NARGV || op == KERN_PROC_NENV) 1885 *oldlenp = sizeof(int); 1886 else 1887 *oldlenp = ARG_MAX; /* XXX XXX XXX */ 1888 return (0); 1889 } 1890 1891 /* Either system process or exiting/zombie */ 1892 if (vpr->ps_flags & (PS_SYSTEM | PS_EXITING)) 1893 return (EINVAL); 1894 1895 /* Execing - danger. */ 1896 if ((vpr->ps_flags & PS_INEXEC)) 1897 return (EBUSY); 1898 1899 /* Only owner or root can get env */ 1900 if ((op == KERN_PROC_NENV || op == KERN_PROC_ENV) && 1901 (vpr->ps_ucred->cr_uid != cp->p_ucred->cr_uid && 1902 (error = suser(cp)) != 0)) 1903 return (error); 1904 1905 ps_strings = vpr->ps_strings; 1906 vm = vpr->ps_vmspace; 1907 uvmspace_addref(vm); 1908 vpr = NULL; 1909 1910 buf = malloc(PAGE_SIZE, M_TEMP, M_WAITOK); 1911 1912 iov.iov_base = &pss; 1913 iov.iov_len = sizeof(pss); 1914 uio.uio_iov = &iov; 1915 uio.uio_iovcnt = 1; 1916 uio.uio_offset = (off_t)ps_strings; 1917 uio.uio_resid = sizeof(pss); 1918 uio.uio_segflg = UIO_SYSSPACE; 1919 uio.uio_rw = UIO_READ; 1920 uio.uio_procp = cp; 1921 1922 if ((error = uvm_io(&vm->vm_map, &uio, 0)) != 0) 1923 goto out; 1924 1925 if (op == KERN_PROC_NARGV) { 1926 error = sysctl_rdint(oldp, oldlenp, NULL, pss.ps_nargvstr); 1927 goto out; 1928 } 1929 if (op == KERN_PROC_NENV) { 1930 error = sysctl_rdint(oldp, oldlenp, NULL, pss.ps_nenvstr); 1931 goto out; 1932 } 1933 1934 if (op == KERN_PROC_ARGV) { 1935 cnt = pss.ps_nargvstr; 1936 vargv = pss.ps_argvstr; 1937 } else { 1938 cnt = pss.ps_nenvstr; 1939 vargv = pss.ps_envstr; 1940 } 1941 1942 /* -1 to have space for a terminating NUL */ 1943 limit = *oldlenp - 1; 1944 *oldlenp = 0; 1945 1946 rargv = oldp; 1947 1948 /* 1949 * *oldlenp - number of bytes copied out into readers buffer. 1950 * limit - maximal number of bytes allowed into readers buffer. 1951 * rarg - pointer into readers buffer where next arg will be stored. 1952 * rargv - pointer into readers buffer where the next rarg pointer 1953 * will be stored. 1954 * vargv - pointer into victim address space where the next argument 1955 * will be read. 1956 */ 1957 1958 /* space for cnt pointers and a NULL */ 1959 rarg = (char *)(rargv + cnt + 1); 1960 *oldlenp += (cnt + 1) * sizeof(char **); 1961 1962 while (cnt > 0 && *oldlenp < limit) { 1963 size_t len, vstrlen; 1964 1965 /* Write to readers argv */ 1966 if ((error = copyout(&rarg, rargv, sizeof(rarg))) != 0) 1967 goto out; 1968 1969 /* read the victim argv */ 1970 iov.iov_base = &varg; 1971 iov.iov_len = sizeof(varg); 1972 uio.uio_iov = &iov; 1973 uio.uio_iovcnt = 1; 1974 uio.uio_offset = (off_t)(vaddr_t)vargv; 1975 uio.uio_resid = sizeof(varg); 1976 uio.uio_segflg = UIO_SYSSPACE; 1977 uio.uio_rw = UIO_READ; 1978 uio.uio_procp = cp; 1979 if ((error = uvm_io(&vm->vm_map, &uio, 0)) != 0) 1980 goto out; 1981 1982 if (varg == NULL) 1983 break; 1984 1985 /* 1986 * read the victim arg. We must jump through hoops to avoid 1987 * crossing a page boundary too much and returning an error. 1988 */ 1989 more: 1990 len = PAGE_SIZE - (((vaddr_t)varg) & PAGE_MASK); 1991 /* leave space for the terminating NUL */ 1992 iov.iov_base = buf; 1993 iov.iov_len = len; 1994 uio.uio_iov = &iov; 1995 uio.uio_iovcnt = 1; 1996 uio.uio_offset = (off_t)(vaddr_t)varg; 1997 uio.uio_resid = len; 1998 uio.uio_segflg = UIO_SYSSPACE; 1999 uio.uio_rw = UIO_READ; 2000 uio.uio_procp = cp; 2001 if ((error = uvm_io(&vm->vm_map, &uio, 0)) != 0) 2002 goto out; 2003 2004 for (vstrlen = 0; vstrlen < len; vstrlen++) { 2005 if (buf[vstrlen] == '\0') 2006 break; 2007 } 2008 2009 /* Don't overflow readers buffer. */ 2010 if (*oldlenp + vstrlen + 1 >= limit) { 2011 error = ENOMEM; 2012 goto out; 2013 } 2014 2015 if ((error = copyout(buf, rarg, vstrlen)) != 0) 2016 goto out; 2017 2018 *oldlenp += vstrlen; 2019 rarg += vstrlen; 2020 2021 /* The string didn't end in this page? */ 2022 if (vstrlen == len) { 2023 varg += vstrlen; 2024 goto more; 2025 } 2026 2027 /* End of string. Terminate it with a NUL */ 2028 buf[0] = '\0'; 2029 if ((error = copyout(buf, rarg, 1)) != 0) 2030 goto out; 2031 *oldlenp += 1; 2032 rarg += 1; 2033 2034 vargv++; 2035 rargv++; 2036 cnt--; 2037 } 2038 2039 if (*oldlenp >= limit) { 2040 error = ENOMEM; 2041 goto out; 2042 } 2043 2044 /* Write the terminating null */ 2045 rarg = NULL; 2046 error = copyout(&rarg, rargv, sizeof(rarg)); 2047 2048 out: 2049 uvmspace_free(vm); 2050 free(buf, M_TEMP, PAGE_SIZE); 2051 return (error); 2052 } 2053 2054 int 2055 sysctl_proc_cwd(int *name, u_int namelen, void *oldp, size_t *oldlenp, 2056 struct proc *cp) 2057 { 2058 struct process *findpr; 2059 struct vnode *vp; 2060 pid_t pid; 2061 int error; 2062 size_t lenused, len; 2063 char *path, *bp, *bend; 2064 2065 if (namelen > 1) 2066 return (ENOTDIR); 2067 if (namelen < 1) 2068 return (EINVAL); 2069 2070 pid = name[0]; 2071 if ((findpr = prfind(pid)) == NULL) 2072 return (ESRCH); 2073 2074 if (oldp == NULL) { 2075 *oldlenp = MAXPATHLEN * 4; 2076 return (0); 2077 } 2078 2079 /* Either system process or exiting/zombie */ 2080 if (findpr->ps_flags & (PS_SYSTEM | PS_EXITING)) 2081 return (EINVAL); 2082 2083 /* Only owner or root can get cwd */ 2084 if (findpr->ps_ucred->cr_uid != cp->p_ucred->cr_uid && 2085 (error = suser(cp)) != 0) 2086 return (error); 2087 2088 len = *oldlenp; 2089 if (len > MAXPATHLEN * 4) 2090 len = MAXPATHLEN * 4; 2091 else if (len < 2) 2092 return (ERANGE); 2093 *oldlenp = 0; 2094 2095 /* snag a reference to the vnode before we can sleep */ 2096 vp = findpr->ps_fd->fd_cdir; 2097 vref(vp); 2098 2099 path = malloc(len, M_TEMP, M_WAITOK); 2100 2101 bp = &path[len]; 2102 bend = bp; 2103 *(--bp) = '\0'; 2104 2105 /* Same as sys__getcwd */ 2106 error = vfs_getcwd_common(vp, NULL, 2107 &bp, path, len / 2, GETCWD_CHECK_ACCESS, cp); 2108 if (error == 0) { 2109 *oldlenp = lenused = bend - bp; 2110 error = copyout(bp, oldp, lenused); 2111 } 2112 2113 vrele(vp); 2114 free(path, M_TEMP, len); 2115 2116 return (error); 2117 } 2118 2119 int 2120 sysctl_proc_nobroadcastkill(int *name, u_int namelen, void *newp, size_t newlen, 2121 void *oldp, size_t *oldlenp, struct proc *cp) 2122 { 2123 struct process *findpr; 2124 pid_t pid; 2125 int error, flag; 2126 2127 if (namelen > 1) 2128 return (ENOTDIR); 2129 if (namelen < 1) 2130 return (EINVAL); 2131 2132 pid = name[0]; 2133 if ((findpr = prfind(pid)) == NULL) 2134 return (ESRCH); 2135 2136 /* Either system process or exiting/zombie */ 2137 if (findpr->ps_flags & (PS_SYSTEM | PS_EXITING)) 2138 return (EINVAL); 2139 2140 /* Only root can change PS_NOBROADCASTKILL */ 2141 if (newp != NULL && (error = suser(cp)) != 0) 2142 return (error); 2143 2144 /* get the PS_NOBROADCASTKILL flag */ 2145 flag = findpr->ps_flags & PS_NOBROADCASTKILL ? 1 : 0; 2146 2147 error = sysctl_int(oldp, oldlenp, newp, newlen, &flag); 2148 if (error == 0 && newp) { 2149 if (flag) 2150 atomic_setbits_int(&findpr->ps_flags, 2151 PS_NOBROADCASTKILL); 2152 else 2153 atomic_clearbits_int(&findpr->ps_flags, 2154 PS_NOBROADCASTKILL); 2155 } 2156 2157 return (error); 2158 } 2159 2160 /* Arbitrary but reasonable limit for one iteration. */ 2161 #define VMMAP_MAXLEN MAXPHYS 2162 2163 int 2164 sysctl_proc_vmmap(int *name, u_int namelen, void *oldp, size_t *oldlenp, 2165 struct proc *cp) 2166 { 2167 struct process *findpr; 2168 pid_t pid; 2169 int error; 2170 size_t oldlen, len; 2171 struct kinfo_vmentry *kve, *ukve; 2172 u_long *ustart, start; 2173 2174 if (namelen > 1) 2175 return (ENOTDIR); 2176 if (namelen < 1) 2177 return (EINVAL); 2178 2179 /* Provide max buffer length as hint. */ 2180 if (oldp == NULL) { 2181 if (oldlenp == NULL) 2182 return (EINVAL); 2183 else { 2184 *oldlenp = VMMAP_MAXLEN; 2185 return (0); 2186 } 2187 } 2188 2189 pid = name[0]; 2190 if (pid == cp->p_p->ps_pid) { 2191 /* Self process mapping. */ 2192 findpr = cp->p_p; 2193 } else if (pid > 0) { 2194 if ((findpr = prfind(pid)) == NULL) 2195 return (ESRCH); 2196 2197 /* Either system process or exiting/zombie */ 2198 if (findpr->ps_flags & (PS_SYSTEM | PS_EXITING)) 2199 return (EINVAL); 2200 2201 #if 1 2202 /* XXX Allow only root for now */ 2203 if ((error = suser(cp)) != 0) 2204 return (error); 2205 #else 2206 /* Only owner or root can get vmmap */ 2207 if (findpr->ps_ucred->cr_uid != cp->p_ucred->cr_uid && 2208 (error = suser(cp)) != 0) 2209 return (error); 2210 #endif 2211 } else { 2212 /* Only root can get kernel_map */ 2213 if ((error = suser(cp)) != 0) 2214 return (error); 2215 findpr = NULL; 2216 } 2217 2218 /* Check the given size. */ 2219 oldlen = *oldlenp; 2220 if (oldlen == 0 || oldlen % sizeof(*kve) != 0) 2221 return (EINVAL); 2222 2223 /* Deny huge allocation. */ 2224 if (oldlen > VMMAP_MAXLEN) 2225 return (EINVAL); 2226 2227 /* 2228 * Iterate from the given address passed as the first element's 2229 * kve_start via oldp. 2230 */ 2231 ukve = (struct kinfo_vmentry *)oldp; 2232 ustart = &ukve->kve_start; 2233 error = copyin(ustart, &start, sizeof(start)); 2234 if (error != 0) 2235 return (error); 2236 2237 /* Allocate wired memory to not block. */ 2238 kve = malloc(oldlen, M_TEMP, M_WAITOK); 2239 2240 /* Set the base address and read entries. */ 2241 kve[0].kve_start = start; 2242 len = oldlen; 2243 error = fill_vmmap(findpr, kve, &len); 2244 if (error != 0 && error != ENOMEM) 2245 goto done; 2246 if (len == 0) 2247 goto done; 2248 2249 KASSERT(len <= oldlen); 2250 KASSERT((len % sizeof(struct kinfo_vmentry)) == 0); 2251 2252 error = copyout(kve, oldp, len); 2253 2254 done: 2255 *oldlenp = len; 2256 2257 free(kve, M_TEMP, oldlen); 2258 2259 return (error); 2260 } 2261 #endif 2262 2263 /* 2264 * Initialize disknames/diskstats for export by sysctl. If update is set, 2265 * then we simply update the disk statistics information. 2266 */ 2267 int 2268 sysctl_diskinit(int update, struct proc *p) 2269 { 2270 struct diskstats *sdk; 2271 struct disk *dk; 2272 const char *duid; 2273 int error, changed = 0; 2274 2275 KERNEL_ASSERT_LOCKED(); 2276 2277 if ((error = rw_enter(&sysctl_disklock, RW_WRITE|RW_INTR)) != 0) 2278 return error; 2279 2280 /* Run in a loop, disks may change while malloc sleeps. */ 2281 while (disk_change) { 2282 int tlen; 2283 2284 disk_change = 0; 2285 2286 tlen = 0; 2287 TAILQ_FOREACH(dk, &disklist, dk_link) { 2288 if (dk->dk_name) 2289 tlen += strlen(dk->dk_name); 2290 tlen += 18; /* label uid + separators */ 2291 } 2292 tlen++; 2293 2294 /* 2295 * The sysctl_disklock ensures that no other process can 2296 * allocate disknames and diskstats while our malloc sleeps. 2297 */ 2298 free(disknames, M_SYSCTL, disknameslen); 2299 free(diskstats, M_SYSCTL, diskstatslen); 2300 diskstats = NULL; 2301 disknames = NULL; 2302 diskstats = mallocarray(disk_count, sizeof(struct diskstats), 2303 M_SYSCTL, M_WAITOK|M_ZERO); 2304 diskstatslen = disk_count * sizeof(struct diskstats); 2305 disknames = malloc(tlen, M_SYSCTL, M_WAITOK|M_ZERO); 2306 disknameslen = tlen; 2307 disknames[0] = '\0'; 2308 changed = 1; 2309 } 2310 2311 if (changed) { 2312 int l; 2313 2314 l = 0; 2315 sdk = diskstats; 2316 TAILQ_FOREACH(dk, &disklist, dk_link) { 2317 duid = NULL; 2318 if (dk->dk_label && !duid_iszero(dk->dk_label->d_uid)) 2319 duid = duid_format(dk->dk_label->d_uid); 2320 snprintf(disknames + l, disknameslen - l, "%s:%s,", 2321 dk->dk_name ? dk->dk_name : "", 2322 duid ? duid : ""); 2323 l += strlen(disknames + l); 2324 strlcpy(sdk->ds_name, dk->dk_name, 2325 sizeof(sdk->ds_name)); 2326 mtx_enter(&dk->dk_mtx); 2327 sdk->ds_busy = dk->dk_busy; 2328 sdk->ds_rxfer = dk->dk_rxfer; 2329 sdk->ds_wxfer = dk->dk_wxfer; 2330 sdk->ds_seek = dk->dk_seek; 2331 sdk->ds_rbytes = dk->dk_rbytes; 2332 sdk->ds_wbytes = dk->dk_wbytes; 2333 sdk->ds_attachtime = dk->dk_attachtime; 2334 sdk->ds_timestamp = dk->dk_timestamp; 2335 sdk->ds_time = dk->dk_time; 2336 mtx_leave(&dk->dk_mtx); 2337 sdk++; 2338 } 2339 2340 /* Eliminate trailing comma */ 2341 if (l != 0) 2342 disknames[l - 1] = '\0'; 2343 } else if (update) { 2344 /* Just update, number of drives hasn't changed */ 2345 sdk = diskstats; 2346 TAILQ_FOREACH(dk, &disklist, dk_link) { 2347 strlcpy(sdk->ds_name, dk->dk_name, 2348 sizeof(sdk->ds_name)); 2349 mtx_enter(&dk->dk_mtx); 2350 sdk->ds_busy = dk->dk_busy; 2351 sdk->ds_rxfer = dk->dk_rxfer; 2352 sdk->ds_wxfer = dk->dk_wxfer; 2353 sdk->ds_seek = dk->dk_seek; 2354 sdk->ds_rbytes = dk->dk_rbytes; 2355 sdk->ds_wbytes = dk->dk_wbytes; 2356 sdk->ds_attachtime = dk->dk_attachtime; 2357 sdk->ds_timestamp = dk->dk_timestamp; 2358 sdk->ds_time = dk->dk_time; 2359 mtx_leave(&dk->dk_mtx); 2360 sdk++; 2361 } 2362 } 2363 rw_exit_write(&sysctl_disklock); 2364 return 0; 2365 } 2366 2367 #if defined(SYSVMSG) || defined(SYSVSEM) || defined(SYSVSHM) 2368 int 2369 sysctl_sysvipc(int *name, u_int namelen, void *where, size_t *sizep) 2370 { 2371 #ifdef SYSVSEM 2372 struct sem_sysctl_info *semsi; 2373 #endif 2374 #ifdef SYSVSHM 2375 struct shm_sysctl_info *shmsi; 2376 #endif 2377 size_t infosize, dssize, tsize, buflen, bufsiz; 2378 int i, nds, error, ret; 2379 void *buf; 2380 2381 if (namelen != 1) 2382 return (EINVAL); 2383 2384 buflen = *sizep; 2385 2386 switch (*name) { 2387 case KERN_SYSVIPC_MSG_INFO: 2388 #ifdef SYSVMSG 2389 return (sysctl_sysvmsg(name, namelen, where, sizep)); 2390 #else 2391 return (EOPNOTSUPP); 2392 #endif 2393 case KERN_SYSVIPC_SEM_INFO: 2394 #ifdef SYSVSEM 2395 infosize = sizeof(semsi->seminfo); 2396 nds = seminfo.semmni; 2397 dssize = sizeof(semsi->semids[0]); 2398 break; 2399 #else 2400 return (EOPNOTSUPP); 2401 #endif 2402 case KERN_SYSVIPC_SHM_INFO: 2403 #ifdef SYSVSHM 2404 infosize = sizeof(shmsi->shminfo); 2405 nds = shminfo.shmmni; 2406 dssize = sizeof(shmsi->shmids[0]); 2407 break; 2408 #else 2409 return (EOPNOTSUPP); 2410 #endif 2411 default: 2412 return (EINVAL); 2413 } 2414 tsize = infosize + (nds * dssize); 2415 2416 /* Return just the total size required. */ 2417 if (where == NULL) { 2418 *sizep = tsize; 2419 return (0); 2420 } 2421 2422 /* Not enough room for even the info struct. */ 2423 if (buflen < infosize) { 2424 *sizep = 0; 2425 return (ENOMEM); 2426 } 2427 bufsiz = min(tsize, buflen); 2428 buf = malloc(bufsiz, M_TEMP, M_WAITOK|M_ZERO); 2429 2430 switch (*name) { 2431 #ifdef SYSVSEM 2432 case KERN_SYSVIPC_SEM_INFO: 2433 semsi = (struct sem_sysctl_info *)buf; 2434 semsi->seminfo = seminfo; 2435 break; 2436 #endif 2437 #ifdef SYSVSHM 2438 case KERN_SYSVIPC_SHM_INFO: 2439 shmsi = (struct shm_sysctl_info *)buf; 2440 shmsi->shminfo = shminfo; 2441 break; 2442 #endif 2443 } 2444 buflen -= infosize; 2445 2446 ret = 0; 2447 if (buflen > 0) { 2448 /* Fill in the IPC data structures. */ 2449 for (i = 0; i < nds; i++) { 2450 if (buflen < dssize) { 2451 ret = ENOMEM; 2452 break; 2453 } 2454 switch (*name) { 2455 #ifdef SYSVSEM 2456 case KERN_SYSVIPC_SEM_INFO: 2457 if (sema[i] != NULL) 2458 memcpy(&semsi->semids[i], sema[i], 2459 dssize); 2460 else 2461 memset(&semsi->semids[i], 0, dssize); 2462 break; 2463 #endif 2464 #ifdef SYSVSHM 2465 case KERN_SYSVIPC_SHM_INFO: 2466 if (shmsegs[i] != NULL) 2467 memcpy(&shmsi->shmids[i], shmsegs[i], 2468 dssize); 2469 else 2470 memset(&shmsi->shmids[i], 0, dssize); 2471 break; 2472 #endif 2473 } 2474 buflen -= dssize; 2475 } 2476 } 2477 *sizep -= buflen; 2478 error = copyout(buf, where, *sizep); 2479 free(buf, M_TEMP, bufsiz); 2480 /* If copyout succeeded, use return code set earlier. */ 2481 return (error ? error : ret); 2482 } 2483 #endif /* SYSVMSG || SYSVSEM || SYSVSHM */ 2484 2485 #ifndef SMALL_KERNEL 2486 2487 int 2488 sysctl_intrcnt(int *name, u_int namelen, void *oldp, size_t *oldlenp) 2489 { 2490 return (evcount_sysctl(name, namelen, oldp, oldlenp, NULL, 0)); 2491 } 2492 2493 2494 int 2495 sysctl_sensors(int *name, u_int namelen, void *oldp, size_t *oldlenp, 2496 void *newp, size_t newlen) 2497 { 2498 struct ksensor *ks; 2499 struct sensor *us; 2500 struct ksensordev *ksd; 2501 struct sensordev *usd; 2502 int dev, numt, ret; 2503 enum sensor_type type; 2504 2505 if (namelen != 1 && namelen != 3) 2506 return (ENOTDIR); 2507 2508 dev = name[0]; 2509 if (namelen == 1) { 2510 ret = sensordev_get(dev, &ksd); 2511 if (ret) 2512 return (ret); 2513 2514 /* Grab a copy, to clear the kernel pointers */ 2515 usd = malloc(sizeof(*usd), M_TEMP, M_WAITOK|M_ZERO); 2516 usd->num = ksd->num; 2517 strlcpy(usd->xname, ksd->xname, sizeof(usd->xname)); 2518 memcpy(usd->maxnumt, ksd->maxnumt, sizeof(usd->maxnumt)); 2519 usd->sensors_count = ksd->sensors_count; 2520 2521 ret = sysctl_rdstruct(oldp, oldlenp, newp, usd, 2522 sizeof(struct sensordev)); 2523 2524 free(usd, M_TEMP, sizeof(*usd)); 2525 return (ret); 2526 } 2527 2528 type = name[1]; 2529 numt = name[2]; 2530 2531 ret = sensor_find(dev, type, numt, &ks); 2532 if (ret) 2533 return (ret); 2534 2535 /* Grab a copy, to clear the kernel pointers */ 2536 us = malloc(sizeof(*us), M_TEMP, M_WAITOK|M_ZERO); 2537 memcpy(us->desc, ks->desc, sizeof(us->desc)); 2538 us->tv = ks->tv; 2539 us->value = ks->value; 2540 us->type = ks->type; 2541 us->status = ks->status; 2542 us->numt = ks->numt; 2543 us->flags = ks->flags; 2544 2545 ret = sysctl_rdstruct(oldp, oldlenp, newp, us, 2546 sizeof(struct sensor)); 2547 free(us, M_TEMP, sizeof(*us)); 2548 return (ret); 2549 } 2550 #endif /* SMALL_KERNEL */ 2551 2552 int 2553 sysctl_cptime2(int *name, u_int namelen, void *oldp, size_t *oldlenp, 2554 void *newp, size_t newlen) 2555 { 2556 CPU_INFO_ITERATOR cii; 2557 struct cpu_info *ci; 2558 int found = 0; 2559 2560 if (namelen != 1) 2561 return (ENOTDIR); 2562 2563 CPU_INFO_FOREACH(cii, ci) { 2564 if (name[0] == CPU_INFO_UNIT(ci)) { 2565 found = 1; 2566 break; 2567 } 2568 } 2569 if (!found) 2570 return (ENOENT); 2571 2572 return (sysctl_rdstruct(oldp, oldlenp, newp, 2573 &ci->ci_schedstate.spc_cp_time, 2574 sizeof(ci->ci_schedstate.spc_cp_time))); 2575 } 2576 2577 #if NAUDIO > 0 2578 int 2579 sysctl_audio(int *name, u_int namelen, void *oldp, size_t *oldlenp, 2580 void *newp, size_t newlen) 2581 { 2582 if (namelen != 1) 2583 return (ENOTDIR); 2584 2585 if (name[0] != KERN_AUDIO_RECORD) 2586 return (ENOENT); 2587 2588 return (sysctl_int(oldp, oldlenp, newp, newlen, &audio_record_enable)); 2589 } 2590 #endif 2591 2592 #if NVIDEO > 0 2593 int 2594 sysctl_video(int *name, u_int namelen, void *oldp, size_t *oldlenp, 2595 void *newp, size_t newlen) 2596 { 2597 if (namelen != 1) 2598 return (ENOTDIR); 2599 2600 if (name[0] != KERN_VIDEO_RECORD) 2601 return (ENOENT); 2602 2603 return (sysctl_int(oldp, oldlenp, newp, newlen, &video_record_enable)); 2604 } 2605 #endif 2606 2607 int 2608 sysctl_cpustats(int *name, u_int namelen, void *oldp, size_t *oldlenp, 2609 void *newp, size_t newlen) 2610 { 2611 CPU_INFO_ITERATOR cii; 2612 struct cpustats cs; 2613 struct cpu_info *ci; 2614 int found = 0; 2615 2616 if (namelen != 1) 2617 return (ENOTDIR); 2618 2619 CPU_INFO_FOREACH(cii, ci) { 2620 if (name[0] == CPU_INFO_UNIT(ci)) { 2621 found = 1; 2622 break; 2623 } 2624 } 2625 if (!found) 2626 return (ENOENT); 2627 2628 memset(&cs, 0, sizeof cs); 2629 memcpy(&cs.cs_time, &ci->ci_schedstate.spc_cp_time, sizeof(cs.cs_time)); 2630 cs.cs_flags = 0; 2631 if (cpu_is_online(ci)) 2632 cs.cs_flags |= CPUSTATS_ONLINE; 2633 2634 return (sysctl_rdstruct(oldp, oldlenp, newp, &cs, sizeof(cs))); 2635 } 2636 2637 int 2638 sysctl_utc_offset(void *oldp, size_t *oldlenp, void *newp, size_t newlen) 2639 { 2640 struct timespec adjusted, now; 2641 int adjustment_seconds, error, new_offset_minutes, old_offset_minutes; 2642 2643 old_offset_minutes = utc_offset / 60; /* seconds -> minutes */ 2644 new_offset_minutes = old_offset_minutes; 2645 error = sysctl_securelevel_int(oldp, oldlenp, newp, newlen, 2646 &new_offset_minutes); 2647 if (error) 2648 return error; 2649 if (new_offset_minutes < -24 * 60 || new_offset_minutes > 24 * 60) 2650 return EINVAL; 2651 if (new_offset_minutes == old_offset_minutes) 2652 return 0; 2653 2654 utc_offset = new_offset_minutes * 60; /* minutes -> seconds */ 2655 adjustment_seconds = (new_offset_minutes - old_offset_minutes) * 60; 2656 2657 nanotime(&now); 2658 adjusted = now; 2659 adjusted.tv_sec -= adjustment_seconds; 2660 tc_setrealtimeclock(&adjusted); 2661 resettodr(); 2662 2663 return 0; 2664 } 2665