1 /* $OpenBSD: kern_sysctl.c,v 1.424 2024/01/19 01:43:27 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 static int page_size = PAGE_SIZE; 670 671 const struct sysctl_bounded_args hw_vars[] = { 672 {HW_NCPU, &ncpus, SYSCTL_INT_READONLY}, 673 {HW_NCPUFOUND, &ncpusfound, SYSCTL_INT_READONLY}, 674 {HW_BYTEORDER, &byte_order, SYSCTL_INT_READONLY}, 675 {HW_PAGESIZE, &page_size, SYSCTL_INT_READONLY}, 676 {HW_DISKCOUNT, &disk_count, SYSCTL_INT_READONLY}, 677 {HW_POWER, &hw_power, SYSCTL_INT_READONLY}, 678 }; 679 680 int 681 hw_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, 682 size_t newlen, struct proc *p) 683 { 684 extern char machine[], cpu_model[]; 685 int err, cpuspeed; 686 687 /* 688 * all sysctl names at this level except sensors and battery 689 * are terminal 690 */ 691 if (name[0] != HW_SENSORS && name[0] != HW_BATTERY && namelen != 1) 692 return (ENOTDIR); /* overloaded */ 693 694 switch (name[0]) { 695 case HW_MACHINE: 696 return (sysctl_rdstring(oldp, oldlenp, newp, machine)); 697 case HW_MODEL: 698 return (sysctl_rdstring(oldp, oldlenp, newp, cpu_model)); 699 case HW_NCPUONLINE: 700 return (sysctl_rdint(oldp, oldlenp, newp, 701 sysctl_hwncpuonline())); 702 case HW_PHYSMEM: 703 return (sysctl_rdint(oldp, oldlenp, newp, ptoa(physmem))); 704 case HW_USERMEM: 705 return (sysctl_rdint(oldp, oldlenp, newp, 706 ptoa(physmem - uvmexp.wired))); 707 case HW_DISKNAMES: 708 err = sysctl_diskinit(0, p); 709 if (err) 710 return err; 711 if (disknames) 712 return (sysctl_rdstring(oldp, oldlenp, newp, 713 disknames)); 714 else 715 return (sysctl_rdstring(oldp, oldlenp, newp, "")); 716 case HW_DISKSTATS: 717 err = sysctl_diskinit(1, p); 718 if (err) 719 return err; 720 return (sysctl_rdstruct(oldp, oldlenp, newp, diskstats, 721 disk_count * sizeof(struct diskstats))); 722 case HW_CPUSPEED: 723 if (!cpu_cpuspeed) 724 return (EOPNOTSUPP); 725 err = cpu_cpuspeed(&cpuspeed); 726 if (err) 727 return err; 728 return (sysctl_rdint(oldp, oldlenp, newp, cpuspeed)); 729 #ifndef SMALL_KERNEL 730 case HW_SENSORS: 731 return (sysctl_sensors(name + 1, namelen - 1, oldp, oldlenp, 732 newp, newlen)); 733 case HW_SETPERF: 734 return (sysctl_hwsetperf(oldp, oldlenp, newp, newlen)); 735 case HW_PERFPOLICY: 736 return (sysctl_hwperfpolicy(oldp, oldlenp, newp, newlen)); 737 #endif /* !SMALL_KERNEL */ 738 case HW_VENDOR: 739 if (hw_vendor) 740 return (sysctl_rdstring(oldp, oldlenp, newp, 741 hw_vendor)); 742 else 743 return (EOPNOTSUPP); 744 case HW_PRODUCT: 745 if (hw_prod) 746 return (sysctl_rdstring(oldp, oldlenp, newp, hw_prod)); 747 else 748 return (EOPNOTSUPP); 749 case HW_VERSION: 750 if (hw_ver) 751 return (sysctl_rdstring(oldp, oldlenp, newp, hw_ver)); 752 else 753 return (EOPNOTSUPP); 754 case HW_SERIALNO: 755 if (hw_serial) 756 return (sysctl_rdstring(oldp, oldlenp, newp, 757 hw_serial)); 758 else 759 return (EOPNOTSUPP); 760 case HW_UUID: 761 if (hw_uuid) 762 return (sysctl_rdstring(oldp, oldlenp, newp, hw_uuid)); 763 else 764 return (EOPNOTSUPP); 765 case HW_PHYSMEM64: 766 return (sysctl_rdquad(oldp, oldlenp, newp, 767 ptoa((psize_t)physmem))); 768 case HW_USERMEM64: 769 return (sysctl_rdquad(oldp, oldlenp, newp, 770 ptoa((psize_t)physmem - uvmexp.wired))); 771 case HW_ALLOWPOWERDOWN: 772 return (sysctl_securelevel_int(oldp, oldlenp, newp, newlen, 773 &allowpowerdown)); 774 #if NUCOM > 0 775 case HW_UCOMNAMES: { 776 const char *str = sysctl_ucominit(); 777 if (str == NULL) 778 return EINVAL; 779 return (sysctl_rdstring(oldp, oldlenp, newp, str)); 780 } 781 #endif /* NUCOM > 0 */ 782 #ifdef __HAVE_CPU_TOPOLOGY 783 case HW_SMT: 784 return (sysctl_hwsmt(oldp, oldlenp, newp, newlen)); 785 #endif 786 #ifndef SMALL_KERNEL 787 case HW_BATTERY: 788 return (sysctl_hwbattery(name + 1, namelen - 1, oldp, oldlenp, 789 newp, newlen)); 790 #endif 791 default: 792 return sysctl_bounded_arr(hw_vars, nitems(hw_vars), name, 793 namelen, oldp, oldlenp, newp, newlen); 794 } 795 /* NOTREACHED */ 796 } 797 798 #ifndef SMALL_KERNEL 799 800 int hw_battery_chargemode; 801 int hw_battery_chargestart; 802 int hw_battery_chargestop; 803 int (*hw_battery_setchargemode)(int); 804 int (*hw_battery_setchargestart)(int); 805 int (*hw_battery_setchargestop)(int); 806 807 int 808 sysctl_hwchargemode(void *oldp, size_t *oldlenp, void *newp, size_t newlen) 809 { 810 int mode = hw_battery_chargemode; 811 int error; 812 813 if (!hw_battery_setchargemode) 814 return EOPNOTSUPP; 815 816 error = sysctl_int_bounded(oldp, oldlenp, newp, newlen, 817 &mode, -1, 1); 818 if (error) 819 return error; 820 821 if (newp != NULL) 822 error = hw_battery_setchargemode(mode); 823 824 return error; 825 } 826 827 int 828 sysctl_hwchargestart(void *oldp, size_t *oldlenp, void *newp, size_t newlen) 829 { 830 int start = hw_battery_chargestart; 831 int error; 832 833 if (!hw_battery_setchargestart) 834 return EOPNOTSUPP; 835 836 error = sysctl_int_bounded(oldp, oldlenp, newp, newlen, 837 &start, 0, 100); 838 if (error) 839 return error; 840 841 if (newp != NULL) 842 error = hw_battery_setchargestart(start); 843 844 return error; 845 } 846 847 int 848 sysctl_hwchargestop(void *oldp, size_t *oldlenp, void *newp, size_t newlen) 849 { 850 int stop = hw_battery_chargestop; 851 int error; 852 853 if (!hw_battery_setchargestop) 854 return EOPNOTSUPP; 855 856 error = sysctl_int_bounded(oldp, oldlenp, newp, newlen, 857 &stop, 0, 100); 858 if (error) 859 return error; 860 861 if (newp != NULL) 862 error = hw_battery_setchargestop(stop); 863 864 return error; 865 } 866 867 int 868 sysctl_hwbattery(int *name, u_int namelen, void *oldp, size_t *oldlenp, 869 void *newp, size_t newlen) 870 { 871 if (namelen != 1) 872 return (ENOTDIR); 873 874 switch (name[0]) { 875 case HW_BATTERY_CHARGEMODE: 876 return (sysctl_hwchargemode(oldp, oldlenp, newp, newlen)); 877 case HW_BATTERY_CHARGESTART: 878 return (sysctl_hwchargestart(oldp, oldlenp, newp, newlen)); 879 case HW_BATTERY_CHARGESTOP: 880 return (sysctl_hwchargestop(oldp, oldlenp, newp, newlen)); 881 default: 882 return (EOPNOTSUPP); 883 } 884 /* NOTREACHED */ 885 } 886 887 #endif 888 889 #ifdef DEBUG_SYSCTL 890 /* 891 * Debugging related system variables. 892 */ 893 extern struct ctldebug debug_vfs_busyprt; 894 struct ctldebug debug1, debug2, debug3, debug4; 895 struct ctldebug debug5, debug6, debug7, debug8, debug9; 896 struct ctldebug debug10, debug11, debug12, debug13, debug14; 897 struct ctldebug debug15, debug16, debug17, debug18, debug19; 898 static struct ctldebug *debugvars[CTL_DEBUG_MAXID] = { 899 &debug_vfs_busyprt, 900 &debug1, &debug2, &debug3, &debug4, 901 &debug5, &debug6, &debug7, &debug8, &debug9, 902 &debug10, &debug11, &debug12, &debug13, &debug14, 903 &debug15, &debug16, &debug17, &debug18, &debug19, 904 }; 905 int 906 debug_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, 907 size_t newlen, struct proc *p) 908 { 909 struct ctldebug *cdp; 910 911 /* all sysctl names at this level are name and field */ 912 if (namelen != 2) 913 return (ENOTDIR); /* overloaded */ 914 if (name[0] < 0 || name[0] >= nitems(debugvars)) 915 return (EOPNOTSUPP); 916 cdp = debugvars[name[0]]; 917 if (cdp->debugname == 0) 918 return (EOPNOTSUPP); 919 switch (name[1]) { 920 case CTL_DEBUG_NAME: 921 return (sysctl_rdstring(oldp, oldlenp, newp, cdp->debugname)); 922 case CTL_DEBUG_VALUE: 923 return (sysctl_int(oldp, oldlenp, newp, newlen, cdp->debugvar)); 924 default: 925 return (EOPNOTSUPP); 926 } 927 /* NOTREACHED */ 928 } 929 #endif /* DEBUG_SYSCTL */ 930 931 /* 932 * Reads, or writes that lower the value 933 */ 934 int 935 sysctl_int_lower(void *oldp, size_t *oldlenp, void *newp, size_t newlen, 936 int *valp) 937 { 938 unsigned int oval = *valp, val = *valp; 939 int error; 940 941 if (newp == NULL) 942 return (sysctl_rdint(oldp, oldlenp, newp, val)); 943 944 if ((error = sysctl_int(oldp, oldlenp, newp, newlen, &val))) 945 return (error); 946 if (val > oval) 947 return (EPERM); /* do not allow raising */ 948 *(unsigned int *)valp = val; 949 return (0); 950 } 951 952 /* 953 * Validate parameters and get old / set new parameters 954 * for an integer-valued sysctl function. 955 */ 956 int 957 sysctl_int(void *oldp, size_t *oldlenp, void *newp, size_t newlen, int *valp) 958 { 959 int error = 0; 960 961 if (oldp && *oldlenp < sizeof(int)) 962 return (ENOMEM); 963 if (newp && newlen != sizeof(int)) 964 return (EINVAL); 965 *oldlenp = sizeof(int); 966 if (oldp) 967 error = copyout(valp, oldp, sizeof(int)); 968 if (error == 0 && newp) 969 error = copyin(newp, valp, sizeof(int)); 970 return (error); 971 } 972 973 /* 974 * As above, but read-only. 975 */ 976 int 977 sysctl_rdint(void *oldp, size_t *oldlenp, void *newp, int val) 978 { 979 int error = 0; 980 981 if (oldp && *oldlenp < sizeof(int)) 982 return (ENOMEM); 983 if (newp) 984 return (EPERM); 985 *oldlenp = sizeof(int); 986 if (oldp) 987 error = copyout((caddr_t)&val, oldp, sizeof(int)); 988 return (error); 989 } 990 991 /* 992 * Selects between sysctl_rdint and sysctl_int according to securelevel. 993 */ 994 int 995 sysctl_securelevel_int(void *oldp, size_t *oldlenp, void *newp, size_t newlen, 996 int *valp) 997 { 998 if (securelevel > 0) 999 return (sysctl_rdint(oldp, oldlenp, newp, *valp)); 1000 return (sysctl_int(oldp, oldlenp, newp, newlen, valp)); 1001 } 1002 1003 /* 1004 * Read-only or bounded integer values. 1005 */ 1006 int 1007 sysctl_int_bounded(void *oldp, size_t *oldlenp, void *newp, size_t newlen, 1008 int *valp, int minimum, int maximum) 1009 { 1010 int val = *valp; 1011 int error; 1012 1013 /* read only */ 1014 if (newp == NULL || minimum > maximum) 1015 return (sysctl_rdint(oldp, oldlenp, newp, val)); 1016 1017 if ((error = sysctl_int(oldp, oldlenp, newp, newlen, &val))) 1018 return (error); 1019 /* outside limits */ 1020 if (val < minimum || maximum < val) 1021 return (EINVAL); 1022 *valp = val; 1023 return (0); 1024 } 1025 1026 /* 1027 * Array of read-only or bounded integer values. 1028 */ 1029 int 1030 sysctl_bounded_arr(const struct sysctl_bounded_args *valpp, u_int valplen, 1031 int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, 1032 size_t newlen) 1033 { 1034 u_int i; 1035 if (namelen != 1) 1036 return (ENOTDIR); 1037 for (i = 0; i < valplen; ++i) { 1038 if (valpp[i].mib == name[0]) { 1039 return (sysctl_int_bounded(oldp, oldlenp, newp, newlen, 1040 valpp[i].var, valpp[i].minimum, valpp[i].maximum)); 1041 } 1042 } 1043 return (EOPNOTSUPP); 1044 } 1045 1046 /* 1047 * Validate parameters and get old / set new parameters 1048 * for an integer-valued sysctl function. 1049 */ 1050 int 1051 sysctl_quad(void *oldp, size_t *oldlenp, void *newp, size_t newlen, 1052 int64_t *valp) 1053 { 1054 int error = 0; 1055 1056 if (oldp && *oldlenp < sizeof(int64_t)) 1057 return (ENOMEM); 1058 if (newp && newlen != sizeof(int64_t)) 1059 return (EINVAL); 1060 *oldlenp = sizeof(int64_t); 1061 if (oldp) 1062 error = copyout(valp, oldp, sizeof(int64_t)); 1063 if (error == 0 && newp) 1064 error = copyin(newp, valp, sizeof(int64_t)); 1065 return (error); 1066 } 1067 1068 /* 1069 * As above, but read-only. 1070 */ 1071 int 1072 sysctl_rdquad(void *oldp, size_t *oldlenp, void *newp, int64_t val) 1073 { 1074 int error = 0; 1075 1076 if (oldp && *oldlenp < sizeof(int64_t)) 1077 return (ENOMEM); 1078 if (newp) 1079 return (EPERM); 1080 *oldlenp = sizeof(int64_t); 1081 if (oldp) 1082 error = copyout((caddr_t)&val, oldp, sizeof(int64_t)); 1083 return (error); 1084 } 1085 1086 /* 1087 * Validate parameters and get old / set new parameters 1088 * for a string-valued sysctl function. 1089 */ 1090 int 1091 sysctl_string(void *oldp, size_t *oldlenp, void *newp, size_t newlen, char *str, 1092 size_t maxlen) 1093 { 1094 return sysctl__string(oldp, oldlenp, newp, newlen, str, maxlen, 0); 1095 } 1096 1097 int 1098 sysctl_tstring(void *oldp, size_t *oldlenp, void *newp, size_t newlen, 1099 char *str, size_t maxlen) 1100 { 1101 return sysctl__string(oldp, oldlenp, newp, newlen, str, maxlen, 1); 1102 } 1103 1104 int 1105 sysctl__string(void *oldp, size_t *oldlenp, void *newp, size_t newlen, 1106 char *str, size_t maxlen, int trunc) 1107 { 1108 size_t len; 1109 int error = 0; 1110 1111 len = strlen(str) + 1; 1112 if (oldp && *oldlenp < len) { 1113 if (trunc == 0 || *oldlenp == 0) 1114 return (ENOMEM); 1115 } 1116 if (newp && newlen >= maxlen) 1117 return (EINVAL); 1118 if (oldp) { 1119 if (trunc && *oldlenp < len) { 1120 len = *oldlenp; 1121 error = copyout(str, oldp, len - 1); 1122 if (error == 0) 1123 error = copyout("", (char *)oldp + len - 1, 1); 1124 } else { 1125 error = copyout(str, oldp, len); 1126 } 1127 } 1128 *oldlenp = len; 1129 if (error == 0 && newp) { 1130 error = copyin(newp, str, newlen); 1131 str[newlen] = 0; 1132 } 1133 return (error); 1134 } 1135 1136 /* 1137 * As above, but read-only. 1138 */ 1139 int 1140 sysctl_rdstring(void *oldp, size_t *oldlenp, void *newp, const char *str) 1141 { 1142 size_t len; 1143 int error = 0; 1144 1145 len = strlen(str) + 1; 1146 if (oldp && *oldlenp < len) 1147 return (ENOMEM); 1148 if (newp) 1149 return (EPERM); 1150 *oldlenp = len; 1151 if (oldp) 1152 error = copyout(str, oldp, len); 1153 return (error); 1154 } 1155 1156 /* 1157 * Validate parameters and get old / set new parameters 1158 * for a structure oriented sysctl function. 1159 */ 1160 int 1161 sysctl_struct(void *oldp, size_t *oldlenp, void *newp, size_t newlen, void *sp, 1162 size_t len) 1163 { 1164 int error = 0; 1165 1166 if (oldp && *oldlenp < len) 1167 return (ENOMEM); 1168 if (newp && newlen > len) 1169 return (EINVAL); 1170 if (oldp) { 1171 *oldlenp = len; 1172 error = copyout(sp, oldp, len); 1173 } 1174 if (error == 0 && newp) 1175 error = copyin(newp, sp, len); 1176 return (error); 1177 } 1178 1179 /* 1180 * Validate parameters and get old parameters 1181 * for a structure oriented sysctl function. 1182 */ 1183 int 1184 sysctl_rdstruct(void *oldp, size_t *oldlenp, void *newp, const void *sp, 1185 size_t len) 1186 { 1187 int error = 0; 1188 1189 if (oldp && *oldlenp < len) 1190 return (ENOMEM); 1191 if (newp) 1192 return (EPERM); 1193 *oldlenp = len; 1194 if (oldp) 1195 error = copyout(sp, oldp, len); 1196 return (error); 1197 } 1198 1199 #ifndef SMALL_KERNEL 1200 void 1201 fill_file(struct kinfo_file *kf, struct file *fp, struct filedesc *fdp, 1202 int fd, struct vnode *vp, struct process *pr, struct proc *p, 1203 struct socket *so, int show_pointers) 1204 { 1205 struct vattr va; 1206 1207 memset(kf, 0, sizeof(*kf)); 1208 1209 kf->fd_fd = fd; /* might not really be an fd */ 1210 1211 if (fp != NULL) { 1212 if (show_pointers) 1213 kf->f_fileaddr = PTRTOINT64(fp); 1214 kf->f_flag = fp->f_flag; 1215 kf->f_iflags = fp->f_iflags; 1216 kf->f_type = fp->f_type; 1217 kf->f_count = fp->f_count; 1218 if (show_pointers) 1219 kf->f_ucred = PTRTOINT64(fp->f_cred); 1220 kf->f_uid = fp->f_cred->cr_uid; 1221 kf->f_gid = fp->f_cred->cr_gid; 1222 if (show_pointers) 1223 kf->f_ops = PTRTOINT64(fp->f_ops); 1224 if (show_pointers) 1225 kf->f_data = PTRTOINT64(fp->f_data); 1226 kf->f_usecount = 0; 1227 1228 if (suser(p) == 0 || p->p_ucred->cr_uid == fp->f_cred->cr_uid) { 1229 mtx_enter(&fp->f_mtx); 1230 kf->f_offset = fp->f_offset; 1231 kf->f_rxfer = fp->f_rxfer; 1232 kf->f_rwfer = fp->f_wxfer; 1233 kf->f_seek = fp->f_seek; 1234 kf->f_rbytes = fp->f_rbytes; 1235 kf->f_wbytes = fp->f_wbytes; 1236 mtx_leave(&fp->f_mtx); 1237 } else 1238 kf->f_offset = -1; 1239 } else if (vp != NULL) { 1240 /* fake it */ 1241 kf->f_type = DTYPE_VNODE; 1242 kf->f_flag = FREAD; 1243 if (fd == KERN_FILE_TRACE) 1244 kf->f_flag |= FWRITE; 1245 } else if (so != NULL) { 1246 /* fake it */ 1247 kf->f_type = DTYPE_SOCKET; 1248 } 1249 1250 /* information about the object associated with this file */ 1251 switch (kf->f_type) { 1252 case DTYPE_VNODE: 1253 if (fp != NULL) 1254 vp = (struct vnode *)fp->f_data; 1255 1256 if (show_pointers) 1257 kf->v_un = PTRTOINT64(vp->v_un.vu_socket); 1258 kf->v_type = vp->v_type; 1259 kf->v_tag = vp->v_tag; 1260 kf->v_flag = vp->v_flag; 1261 if (show_pointers) 1262 kf->v_data = PTRTOINT64(vp->v_data); 1263 if (show_pointers) 1264 kf->v_mount = PTRTOINT64(vp->v_mount); 1265 if (vp->v_mount) 1266 strlcpy(kf->f_mntonname, 1267 vp->v_mount->mnt_stat.f_mntonname, 1268 sizeof(kf->f_mntonname)); 1269 1270 if (VOP_GETATTR(vp, &va, p->p_ucred, p) == 0) { 1271 kf->va_fileid = va.va_fileid; 1272 kf->va_mode = MAKEIMODE(va.va_type, va.va_mode); 1273 kf->va_size = va.va_size; 1274 kf->va_rdev = va.va_rdev; 1275 kf->va_fsid = va.va_fsid & 0xffffffff; 1276 kf->va_nlink = va.va_nlink; 1277 } 1278 break; 1279 1280 case DTYPE_SOCKET: { 1281 int locked = 0; 1282 1283 if (so == NULL) { 1284 so = (struct socket *)fp->f_data; 1285 /* if so is passed as parameter it is already locked */ 1286 solock(so); 1287 locked = 1; 1288 } 1289 1290 kf->so_type = so->so_type; 1291 kf->so_state = so->so_state | so->so_snd.sb_state | 1292 so->so_rcv.sb_state; 1293 if (show_pointers) 1294 kf->so_pcb = PTRTOINT64(so->so_pcb); 1295 else 1296 kf->so_pcb = -1; 1297 kf->so_protocol = so->so_proto->pr_protocol; 1298 kf->so_family = so->so_proto->pr_domain->dom_family; 1299 kf->so_rcv_cc = so->so_rcv.sb_cc; 1300 kf->so_snd_cc = so->so_snd.sb_cc; 1301 if (isspliced(so)) { 1302 if (show_pointers) 1303 kf->so_splice = 1304 PTRTOINT64(so->so_sp->ssp_socket); 1305 kf->so_splicelen = so->so_sp->ssp_len; 1306 } else if (issplicedback(so)) 1307 kf->so_splicelen = -1; 1308 if (so->so_pcb == NULL) { 1309 if (locked) 1310 sounlock(so); 1311 break; 1312 } 1313 switch (kf->so_family) { 1314 case AF_INET: { 1315 struct inpcb *inpcb = so->so_pcb; 1316 1317 soassertlocked(so); 1318 if (show_pointers) 1319 kf->inp_ppcb = PTRTOINT64(inpcb->inp_ppcb); 1320 kf->inp_lport = inpcb->inp_lport; 1321 kf->inp_laddru[0] = inpcb->inp_laddr.s_addr; 1322 kf->inp_fport = inpcb->inp_fport; 1323 kf->inp_faddru[0] = inpcb->inp_faddr.s_addr; 1324 kf->inp_rtableid = inpcb->inp_rtableid; 1325 if (so->so_type == SOCK_RAW) 1326 kf->inp_proto = inpcb->inp_ip.ip_p; 1327 if (so->so_proto->pr_protocol == IPPROTO_TCP) { 1328 struct tcpcb *tcpcb = (void *)inpcb->inp_ppcb; 1329 kf->t_rcv_wnd = tcpcb->rcv_wnd; 1330 kf->t_snd_wnd = tcpcb->snd_wnd; 1331 kf->t_snd_cwnd = tcpcb->snd_cwnd; 1332 kf->t_state = tcpcb->t_state; 1333 } 1334 break; 1335 } 1336 case AF_INET6: { 1337 struct inpcb *inpcb = so->so_pcb; 1338 1339 soassertlocked(so); 1340 if (show_pointers) 1341 kf->inp_ppcb = PTRTOINT64(inpcb->inp_ppcb); 1342 kf->inp_lport = inpcb->inp_lport; 1343 kf->inp_laddru[0] = inpcb->inp_laddr6.s6_addr32[0]; 1344 kf->inp_laddru[1] = inpcb->inp_laddr6.s6_addr32[1]; 1345 kf->inp_laddru[2] = inpcb->inp_laddr6.s6_addr32[2]; 1346 kf->inp_laddru[3] = inpcb->inp_laddr6.s6_addr32[3]; 1347 kf->inp_fport = inpcb->inp_fport; 1348 kf->inp_faddru[0] = inpcb->inp_faddr6.s6_addr32[0]; 1349 kf->inp_faddru[1] = inpcb->inp_faddr6.s6_addr32[1]; 1350 kf->inp_faddru[2] = inpcb->inp_faddr6.s6_addr32[2]; 1351 kf->inp_faddru[3] = inpcb->inp_faddr6.s6_addr32[3]; 1352 kf->inp_rtableid = inpcb->inp_rtableid; 1353 if (so->so_type == SOCK_RAW) 1354 kf->inp_proto = inpcb->inp_ipv6.ip6_nxt; 1355 if (so->so_proto->pr_protocol == IPPROTO_TCP) { 1356 struct tcpcb *tcpcb = (void *)inpcb->inp_ppcb; 1357 kf->t_rcv_wnd = tcpcb->rcv_wnd; 1358 kf->t_snd_wnd = tcpcb->snd_wnd; 1359 kf->t_state = tcpcb->t_state; 1360 } 1361 break; 1362 } 1363 case AF_UNIX: { 1364 struct unpcb *unpcb = so->so_pcb; 1365 1366 kf->f_msgcount = unpcb->unp_msgcount; 1367 if (show_pointers) { 1368 kf->unp_conn = PTRTOINT64(unpcb->unp_conn); 1369 kf->unp_refs = PTRTOINT64( 1370 SLIST_FIRST(&unpcb->unp_refs)); 1371 kf->unp_nextref = PTRTOINT64( 1372 SLIST_NEXT(unpcb, unp_nextref)); 1373 kf->v_un = PTRTOINT64(unpcb->unp_vnode); 1374 kf->unp_addr = PTRTOINT64(unpcb->unp_addr); 1375 } 1376 if (unpcb->unp_addr != NULL) { 1377 struct sockaddr_un *un = mtod(unpcb->unp_addr, 1378 struct sockaddr_un *); 1379 memcpy(kf->unp_path, un->sun_path, un->sun_len 1380 - offsetof(struct sockaddr_un,sun_path)); 1381 } 1382 break; 1383 } 1384 } 1385 if (locked) 1386 sounlock(so); 1387 break; 1388 } 1389 1390 case DTYPE_PIPE: { 1391 struct pipe *pipe = (struct pipe *)fp->f_data; 1392 1393 if (show_pointers) 1394 kf->pipe_peer = PTRTOINT64(pipe->pipe_peer); 1395 kf->pipe_state = pipe->pipe_state; 1396 break; 1397 } 1398 1399 case DTYPE_KQUEUE: { 1400 struct kqueue *kqi = (struct kqueue *)fp->f_data; 1401 1402 kf->kq_count = kqi->kq_count; 1403 kf->kq_state = kqi->kq_state; 1404 break; 1405 } 1406 } 1407 1408 /* per-process information for KERN_FILE_BY[PU]ID */ 1409 if (pr != NULL) { 1410 kf->p_pid = pr->ps_pid; 1411 kf->p_uid = pr->ps_ucred->cr_uid; 1412 kf->p_gid = pr->ps_ucred->cr_gid; 1413 kf->p_tid = -1; 1414 strlcpy(kf->p_comm, pr->ps_comm, sizeof(kf->p_comm)); 1415 } 1416 if (fdp != NULL) { 1417 fdplock(fdp); 1418 kf->fd_ofileflags = fdp->fd_ofileflags[fd]; 1419 fdpunlock(fdp); 1420 } 1421 } 1422 1423 /* 1424 * Get file structures. 1425 */ 1426 int 1427 sysctl_file(int *name, u_int namelen, char *where, size_t *sizep, 1428 struct proc *p) 1429 { 1430 struct kinfo_file *kf; 1431 struct filedesc *fdp; 1432 struct file *fp; 1433 struct process *pr; 1434 size_t buflen, elem_size, elem_count, outsize; 1435 char *dp = where; 1436 int arg, i, error = 0, needed = 0, matched; 1437 u_int op; 1438 int show_pointers; 1439 1440 if (namelen > 4) 1441 return (ENOTDIR); 1442 if (namelen < 4 || name[2] > sizeof(*kf)) 1443 return (EINVAL); 1444 1445 buflen = where != NULL ? *sizep : 0; 1446 op = name[0]; 1447 arg = name[1]; 1448 elem_size = name[2]; 1449 elem_count = name[3]; 1450 outsize = MIN(sizeof(*kf), elem_size); 1451 1452 if (elem_size < 1) 1453 return (EINVAL); 1454 1455 show_pointers = suser(curproc) == 0; 1456 1457 kf = malloc(sizeof(*kf), M_TEMP, M_WAITOK); 1458 1459 #define FILLIT2(fp, fdp, i, vp, pr, so) do { \ 1460 if (buflen >= elem_size && elem_count > 0) { \ 1461 fill_file(kf, fp, fdp, i, vp, pr, p, so, show_pointers);\ 1462 error = copyout(kf, dp, outsize); \ 1463 if (error) \ 1464 break; \ 1465 dp += elem_size; \ 1466 buflen -= elem_size; \ 1467 elem_count--; \ 1468 } \ 1469 needed += elem_size; \ 1470 } while (0) 1471 #define FILLIT(fp, fdp, i, vp, pr) \ 1472 FILLIT2(fp, fdp, i, vp, pr, NULL) 1473 #define FILLSO(so) \ 1474 FILLIT2(NULL, NULL, 0, NULL, NULL, so) 1475 1476 switch (op) { 1477 case KERN_FILE_BYFILE: 1478 /* use the inp-tables to pick up closed connections, too */ 1479 if (arg == DTYPE_SOCKET) { 1480 struct inpcb *inp; 1481 1482 NET_LOCK(); 1483 mtx_enter(&tcbtable.inpt_mtx); 1484 TAILQ_FOREACH(inp, &tcbtable.inpt_queue, inp_queue) 1485 FILLSO(inp->inp_socket); 1486 mtx_leave(&tcbtable.inpt_mtx); 1487 mtx_enter(&udbtable.inpt_mtx); 1488 TAILQ_FOREACH(inp, &udbtable.inpt_queue, inp_queue) 1489 FILLSO(inp->inp_socket); 1490 mtx_leave(&udbtable.inpt_mtx); 1491 #ifdef INET6 1492 mtx_enter(&udb6table.inpt_mtx); 1493 TAILQ_FOREACH(inp, &udb6table.inpt_queue, inp_queue) 1494 FILLSO(inp->inp_socket); 1495 mtx_leave(&udb6table.inpt_mtx); 1496 #endif 1497 mtx_enter(&rawcbtable.inpt_mtx); 1498 TAILQ_FOREACH(inp, &rawcbtable.inpt_queue, inp_queue) 1499 FILLSO(inp->inp_socket); 1500 mtx_leave(&rawcbtable.inpt_mtx); 1501 #ifdef INET6 1502 mtx_enter(&rawin6pcbtable.inpt_mtx); 1503 TAILQ_FOREACH(inp, &rawin6pcbtable.inpt_queue, 1504 inp_queue) 1505 FILLSO(inp->inp_socket); 1506 mtx_leave(&rawin6pcbtable.inpt_mtx); 1507 #endif 1508 NET_UNLOCK(); 1509 } 1510 fp = NULL; 1511 while ((fp = fd_iterfile(fp, p)) != NULL) { 1512 if ((arg == 0 || fp->f_type == arg)) { 1513 int af, skip = 0; 1514 if (arg == DTYPE_SOCKET && fp->f_type == arg) { 1515 af = ((struct socket *)fp->f_data)-> 1516 so_proto->pr_domain->dom_family; 1517 if (af == AF_INET || af == AF_INET6) 1518 skip = 1; 1519 } 1520 if (!skip) 1521 FILLIT(fp, NULL, 0, NULL, NULL); 1522 } 1523 } 1524 break; 1525 case KERN_FILE_BYPID: 1526 /* A arg of -1 indicates all processes */ 1527 if (arg < -1) { 1528 error = EINVAL; 1529 break; 1530 } 1531 matched = 0; 1532 LIST_FOREACH(pr, &allprocess, ps_list) { 1533 /* 1534 * skip system, exiting, embryonic and undead 1535 * processes 1536 */ 1537 if (pr->ps_flags & (PS_SYSTEM | PS_EMBRYO | PS_EXITING)) 1538 continue; 1539 if (arg > 0 && pr->ps_pid != (pid_t)arg) { 1540 /* not the pid we are looking for */ 1541 continue; 1542 } 1543 matched = 1; 1544 fdp = pr->ps_fd; 1545 if (pr->ps_textvp) 1546 FILLIT(NULL, NULL, KERN_FILE_TEXT, pr->ps_textvp, pr); 1547 if (fdp->fd_cdir) 1548 FILLIT(NULL, NULL, KERN_FILE_CDIR, fdp->fd_cdir, pr); 1549 if (fdp->fd_rdir) 1550 FILLIT(NULL, NULL, KERN_FILE_RDIR, fdp->fd_rdir, pr); 1551 if (pr->ps_tracevp) 1552 FILLIT(NULL, NULL, KERN_FILE_TRACE, pr->ps_tracevp, pr); 1553 for (i = 0; i < fdp->fd_nfiles; i++) { 1554 if ((fp = fd_getfile(fdp, i)) == NULL) 1555 continue; 1556 FILLIT(fp, fdp, i, NULL, pr); 1557 FRELE(fp, p); 1558 } 1559 } 1560 if (!matched) 1561 error = ESRCH; 1562 break; 1563 case KERN_FILE_BYUID: 1564 LIST_FOREACH(pr, &allprocess, ps_list) { 1565 /* 1566 * skip system, exiting, embryonic and undead 1567 * processes 1568 */ 1569 if (pr->ps_flags & (PS_SYSTEM | PS_EMBRYO | PS_EXITING)) 1570 continue; 1571 if (arg >= 0 && pr->ps_ucred->cr_uid != (uid_t)arg) { 1572 /* not the uid we are looking for */ 1573 continue; 1574 } 1575 fdp = pr->ps_fd; 1576 if (fdp->fd_cdir) 1577 FILLIT(NULL, NULL, KERN_FILE_CDIR, fdp->fd_cdir, pr); 1578 if (fdp->fd_rdir) 1579 FILLIT(NULL, NULL, KERN_FILE_RDIR, fdp->fd_rdir, pr); 1580 if (pr->ps_tracevp) 1581 FILLIT(NULL, NULL, KERN_FILE_TRACE, pr->ps_tracevp, pr); 1582 for (i = 0; i < fdp->fd_nfiles; i++) { 1583 if ((fp = fd_getfile(fdp, i)) == NULL) 1584 continue; 1585 FILLIT(fp, fdp, i, NULL, pr); 1586 FRELE(fp, p); 1587 } 1588 } 1589 break; 1590 default: 1591 error = EINVAL; 1592 break; 1593 } 1594 free(kf, M_TEMP, sizeof(*kf)); 1595 1596 if (!error) { 1597 if (where == NULL) 1598 needed += KERN_FILESLOP * elem_size; 1599 else if (*sizep < needed) 1600 error = ENOMEM; 1601 *sizep = needed; 1602 } 1603 1604 return (error); 1605 } 1606 1607 /* 1608 * try over estimating by 5 procs 1609 */ 1610 #define KERN_PROCSLOP 5 1611 1612 int 1613 sysctl_doproc(int *name, u_int namelen, char *where, size_t *sizep) 1614 { 1615 struct kinfo_proc *kproc = NULL; 1616 struct proc *p; 1617 struct process *pr; 1618 char *dp; 1619 int arg, buflen, doingzomb, elem_size, elem_count; 1620 int error, needed, op; 1621 int dothreads = 0; 1622 int show_pointers; 1623 1624 dp = where; 1625 buflen = where != NULL ? *sizep : 0; 1626 needed = error = 0; 1627 1628 if (namelen != 4 || name[2] <= 0 || name[3] < 0 || 1629 name[2] > sizeof(*kproc)) 1630 return (EINVAL); 1631 op = name[0]; 1632 arg = name[1]; 1633 elem_size = name[2]; 1634 elem_count = name[3]; 1635 1636 dothreads = op & KERN_PROC_SHOW_THREADS; 1637 op &= ~KERN_PROC_SHOW_THREADS; 1638 1639 show_pointers = suser(curproc) == 0; 1640 1641 if (where != NULL) 1642 kproc = malloc(sizeof(*kproc), M_TEMP, M_WAITOK); 1643 1644 pr = LIST_FIRST(&allprocess); 1645 doingzomb = 0; 1646 again: 1647 for (; pr != NULL; pr = LIST_NEXT(pr, ps_list)) { 1648 /* XXX skip processes in the middle of being zapped */ 1649 if (pr->ps_pgrp == NULL) 1650 continue; 1651 1652 /* 1653 * Skip embryonic processes. 1654 */ 1655 if (pr->ps_flags & PS_EMBRYO) 1656 continue; 1657 1658 /* 1659 * TODO - make more efficient (see notes below). 1660 */ 1661 switch (op) { 1662 1663 case KERN_PROC_PID: 1664 /* could do this with just a lookup */ 1665 if (pr->ps_pid != (pid_t)arg) 1666 continue; 1667 break; 1668 1669 case KERN_PROC_PGRP: 1670 /* could do this by traversing pgrp */ 1671 if (pr->ps_pgrp->pg_id != (pid_t)arg) 1672 continue; 1673 break; 1674 1675 case KERN_PROC_SESSION: 1676 if (pr->ps_session->s_leader == NULL || 1677 pr->ps_session->s_leader->ps_pid != (pid_t)arg) 1678 continue; 1679 break; 1680 1681 case KERN_PROC_TTY: 1682 if ((pr->ps_flags & PS_CONTROLT) == 0 || 1683 pr->ps_session->s_ttyp == NULL || 1684 pr->ps_session->s_ttyp->t_dev != (dev_t)arg) 1685 continue; 1686 break; 1687 1688 case KERN_PROC_UID: 1689 if (pr->ps_ucred->cr_uid != (uid_t)arg) 1690 continue; 1691 break; 1692 1693 case KERN_PROC_RUID: 1694 if (pr->ps_ucred->cr_ruid != (uid_t)arg) 1695 continue; 1696 break; 1697 1698 case KERN_PROC_ALL: 1699 if (pr->ps_flags & PS_SYSTEM) 1700 continue; 1701 break; 1702 1703 case KERN_PROC_KTHREAD: 1704 /* no filtering */ 1705 break; 1706 1707 default: 1708 error = EINVAL; 1709 goto err; 1710 } 1711 1712 if (buflen >= elem_size && elem_count > 0) { 1713 fill_kproc(pr, kproc, NULL, show_pointers); 1714 error = copyout(kproc, dp, elem_size); 1715 if (error) 1716 goto err; 1717 dp += elem_size; 1718 buflen -= elem_size; 1719 elem_count--; 1720 } 1721 needed += elem_size; 1722 1723 /* Skip per-thread entries if not required by op */ 1724 if (!dothreads) 1725 continue; 1726 1727 TAILQ_FOREACH(p, &pr->ps_threads, p_thr_link) { 1728 if (buflen >= elem_size && elem_count > 0) { 1729 fill_kproc(pr, kproc, p, show_pointers); 1730 error = copyout(kproc, dp, elem_size); 1731 if (error) 1732 goto err; 1733 dp += elem_size; 1734 buflen -= elem_size; 1735 elem_count--; 1736 } 1737 needed += elem_size; 1738 } 1739 } 1740 if (doingzomb == 0) { 1741 pr = LIST_FIRST(&zombprocess); 1742 doingzomb++; 1743 goto again; 1744 } 1745 if (where != NULL) { 1746 *sizep = dp - where; 1747 if (needed > *sizep) { 1748 error = ENOMEM; 1749 goto err; 1750 } 1751 } else { 1752 needed += KERN_PROCSLOP * elem_size; 1753 *sizep = needed; 1754 } 1755 err: 1756 if (kproc) 1757 free(kproc, M_TEMP, sizeof(*kproc)); 1758 return (error); 1759 } 1760 1761 /* 1762 * Fill in a kproc structure for the specified process. 1763 */ 1764 void 1765 fill_kproc(struct process *pr, struct kinfo_proc *ki, struct proc *p, 1766 int show_pointers) 1767 { 1768 struct session *s = pr->ps_session; 1769 struct tty *tp; 1770 struct vmspace *vm = pr->ps_vmspace; 1771 struct timespec booted, st, ut, utc; 1772 int isthread; 1773 1774 isthread = p != NULL; 1775 if (!isthread) 1776 p = pr->ps_mainproc; /* XXX */ 1777 1778 FILL_KPROC(ki, strlcpy, p, pr, pr->ps_ucred, pr->ps_pgrp, 1779 p, pr, s, vm, pr->ps_limit, pr->ps_sigacts, isthread, 1780 show_pointers); 1781 1782 /* stuff that's too painful to generalize into the macros */ 1783 if (pr->ps_pptr) 1784 ki->p_ppid = pr->ps_ppid; 1785 if (s->s_leader) 1786 ki->p_sid = s->s_leader->ps_pid; 1787 1788 if ((pr->ps_flags & PS_CONTROLT) && (tp = s->s_ttyp)) { 1789 ki->p_tdev = tp->t_dev; 1790 ki->p_tpgid = tp->t_pgrp ? tp->t_pgrp->pg_id : -1; 1791 if (show_pointers) 1792 ki->p_tsess = PTRTOINT64(tp->t_session); 1793 } else { 1794 ki->p_tdev = NODEV; 1795 ki->p_tpgid = -1; 1796 } 1797 1798 /* fixups that can only be done in the kernel */ 1799 if ((pr->ps_flags & PS_ZOMBIE) == 0) { 1800 if ((pr->ps_flags & PS_EMBRYO) == 0 && vm != NULL) 1801 ki->p_vm_rssize = vm_resident_count(vm); 1802 calctsru(isthread ? &p->p_tu : &pr->ps_tu, &ut, &st, NULL); 1803 ki->p_uutime_sec = ut.tv_sec; 1804 ki->p_uutime_usec = ut.tv_nsec/1000; 1805 ki->p_ustime_sec = st.tv_sec; 1806 ki->p_ustime_usec = st.tv_nsec/1000; 1807 1808 /* Convert starting uptime to a starting UTC time. */ 1809 nanoboottime(&booted); 1810 timespecadd(&booted, &pr->ps_start, &utc); 1811 ki->p_ustart_sec = utc.tv_sec; 1812 ki->p_ustart_usec = utc.tv_nsec / 1000; 1813 1814 #ifdef MULTIPROCESSOR 1815 if (p->p_cpu != NULL) 1816 ki->p_cpuid = CPU_INFO_UNIT(p->p_cpu); 1817 #endif 1818 } 1819 1820 /* get %cpu and schedule state: just one thread or sum of all? */ 1821 if (isthread) { 1822 ki->p_pctcpu = p->p_pctcpu; 1823 ki->p_stat = p->p_stat; 1824 } else { 1825 ki->p_pctcpu = 0; 1826 ki->p_stat = (pr->ps_flags & PS_ZOMBIE) ? SDEAD : SIDL; 1827 TAILQ_FOREACH(p, &pr->ps_threads, p_thr_link) { 1828 ki->p_pctcpu += p->p_pctcpu; 1829 /* find best state: ONPROC > RUN > STOP > SLEEP > .. */ 1830 if (p->p_stat == SONPROC || ki->p_stat == SONPROC) 1831 ki->p_stat = SONPROC; 1832 else if (p->p_stat == SRUN || ki->p_stat == SRUN) 1833 ki->p_stat = SRUN; 1834 else if (p->p_stat == SSTOP || ki->p_stat == SSTOP) 1835 ki->p_stat = SSTOP; 1836 else if (p->p_stat == SSLEEP) 1837 ki->p_stat = SSLEEP; 1838 } 1839 } 1840 } 1841 1842 int 1843 sysctl_proc_args(int *name, u_int namelen, void *oldp, size_t *oldlenp, 1844 struct proc *cp) 1845 { 1846 struct process *vpr; 1847 pid_t pid; 1848 struct ps_strings pss; 1849 struct iovec iov; 1850 struct uio uio; 1851 int error, cnt, op; 1852 size_t limit; 1853 char **rargv, **vargv; /* reader vs. victim */ 1854 char *rarg, *varg, *buf; 1855 struct vmspace *vm; 1856 vaddr_t ps_strings; 1857 1858 if (namelen > 2) 1859 return (ENOTDIR); 1860 if (namelen < 2) 1861 return (EINVAL); 1862 1863 pid = name[0]; 1864 op = name[1]; 1865 1866 switch (op) { 1867 case KERN_PROC_ARGV: 1868 case KERN_PROC_NARGV: 1869 case KERN_PROC_ENV: 1870 case KERN_PROC_NENV: 1871 break; 1872 default: 1873 return (EOPNOTSUPP); 1874 } 1875 1876 if ((vpr = prfind(pid)) == NULL) 1877 return (ESRCH); 1878 1879 if (oldp == NULL) { 1880 if (op == KERN_PROC_NARGV || op == KERN_PROC_NENV) 1881 *oldlenp = sizeof(int); 1882 else 1883 *oldlenp = ARG_MAX; /* XXX XXX XXX */ 1884 return (0); 1885 } 1886 1887 /* Either system process or exiting/zombie */ 1888 if (vpr->ps_flags & (PS_SYSTEM | PS_EXITING)) 1889 return (EINVAL); 1890 1891 /* Execing - danger. */ 1892 if ((vpr->ps_flags & PS_INEXEC)) 1893 return (EBUSY); 1894 1895 /* Only owner or root can get env */ 1896 if ((op == KERN_PROC_NENV || op == KERN_PROC_ENV) && 1897 (vpr->ps_ucred->cr_uid != cp->p_ucred->cr_uid && 1898 (error = suser(cp)) != 0)) 1899 return (error); 1900 1901 ps_strings = vpr->ps_strings; 1902 vm = vpr->ps_vmspace; 1903 uvmspace_addref(vm); 1904 vpr = NULL; 1905 1906 buf = malloc(PAGE_SIZE, M_TEMP, M_WAITOK); 1907 1908 iov.iov_base = &pss; 1909 iov.iov_len = sizeof(pss); 1910 uio.uio_iov = &iov; 1911 uio.uio_iovcnt = 1; 1912 uio.uio_offset = (off_t)ps_strings; 1913 uio.uio_resid = sizeof(pss); 1914 uio.uio_segflg = UIO_SYSSPACE; 1915 uio.uio_rw = UIO_READ; 1916 uio.uio_procp = cp; 1917 1918 if ((error = uvm_io(&vm->vm_map, &uio, 0)) != 0) 1919 goto out; 1920 1921 if (op == KERN_PROC_NARGV) { 1922 error = sysctl_rdint(oldp, oldlenp, NULL, pss.ps_nargvstr); 1923 goto out; 1924 } 1925 if (op == KERN_PROC_NENV) { 1926 error = sysctl_rdint(oldp, oldlenp, NULL, pss.ps_nenvstr); 1927 goto out; 1928 } 1929 1930 if (op == KERN_PROC_ARGV) { 1931 cnt = pss.ps_nargvstr; 1932 vargv = pss.ps_argvstr; 1933 } else { 1934 cnt = pss.ps_nenvstr; 1935 vargv = pss.ps_envstr; 1936 } 1937 1938 /* -1 to have space for a terminating NUL */ 1939 limit = *oldlenp - 1; 1940 *oldlenp = 0; 1941 1942 rargv = oldp; 1943 1944 /* 1945 * *oldlenp - number of bytes copied out into readers buffer. 1946 * limit - maximal number of bytes allowed into readers buffer. 1947 * rarg - pointer into readers buffer where next arg will be stored. 1948 * rargv - pointer into readers buffer where the next rarg pointer 1949 * will be stored. 1950 * vargv - pointer into victim address space where the next argument 1951 * will be read. 1952 */ 1953 1954 /* space for cnt pointers and a NULL */ 1955 rarg = (char *)(rargv + cnt + 1); 1956 *oldlenp += (cnt + 1) * sizeof(char **); 1957 1958 while (cnt > 0 && *oldlenp < limit) { 1959 size_t len, vstrlen; 1960 1961 /* Write to readers argv */ 1962 if ((error = copyout(&rarg, rargv, sizeof(rarg))) != 0) 1963 goto out; 1964 1965 /* read the victim argv */ 1966 iov.iov_base = &varg; 1967 iov.iov_len = sizeof(varg); 1968 uio.uio_iov = &iov; 1969 uio.uio_iovcnt = 1; 1970 uio.uio_offset = (off_t)(vaddr_t)vargv; 1971 uio.uio_resid = sizeof(varg); 1972 uio.uio_segflg = UIO_SYSSPACE; 1973 uio.uio_rw = UIO_READ; 1974 uio.uio_procp = cp; 1975 if ((error = uvm_io(&vm->vm_map, &uio, 0)) != 0) 1976 goto out; 1977 1978 if (varg == NULL) 1979 break; 1980 1981 /* 1982 * read the victim arg. We must jump through hoops to avoid 1983 * crossing a page boundary too much and returning an error. 1984 */ 1985 more: 1986 len = PAGE_SIZE - (((vaddr_t)varg) & PAGE_MASK); 1987 /* leave space for the terminating NUL */ 1988 iov.iov_base = buf; 1989 iov.iov_len = len; 1990 uio.uio_iov = &iov; 1991 uio.uio_iovcnt = 1; 1992 uio.uio_offset = (off_t)(vaddr_t)varg; 1993 uio.uio_resid = len; 1994 uio.uio_segflg = UIO_SYSSPACE; 1995 uio.uio_rw = UIO_READ; 1996 uio.uio_procp = cp; 1997 if ((error = uvm_io(&vm->vm_map, &uio, 0)) != 0) 1998 goto out; 1999 2000 for (vstrlen = 0; vstrlen < len; vstrlen++) { 2001 if (buf[vstrlen] == '\0') 2002 break; 2003 } 2004 2005 /* Don't overflow readers buffer. */ 2006 if (*oldlenp + vstrlen + 1 >= limit) { 2007 error = ENOMEM; 2008 goto out; 2009 } 2010 2011 if ((error = copyout(buf, rarg, vstrlen)) != 0) 2012 goto out; 2013 2014 *oldlenp += vstrlen; 2015 rarg += vstrlen; 2016 2017 /* The string didn't end in this page? */ 2018 if (vstrlen == len) { 2019 varg += vstrlen; 2020 goto more; 2021 } 2022 2023 /* End of string. Terminate it with a NUL */ 2024 buf[0] = '\0'; 2025 if ((error = copyout(buf, rarg, 1)) != 0) 2026 goto out; 2027 *oldlenp += 1; 2028 rarg += 1; 2029 2030 vargv++; 2031 rargv++; 2032 cnt--; 2033 } 2034 2035 if (*oldlenp >= limit) { 2036 error = ENOMEM; 2037 goto out; 2038 } 2039 2040 /* Write the terminating null */ 2041 rarg = NULL; 2042 error = copyout(&rarg, rargv, sizeof(rarg)); 2043 2044 out: 2045 uvmspace_free(vm); 2046 free(buf, M_TEMP, PAGE_SIZE); 2047 return (error); 2048 } 2049 2050 int 2051 sysctl_proc_cwd(int *name, u_int namelen, void *oldp, size_t *oldlenp, 2052 struct proc *cp) 2053 { 2054 struct process *findpr; 2055 struct vnode *vp; 2056 pid_t pid; 2057 int error; 2058 size_t lenused, len; 2059 char *path, *bp, *bend; 2060 2061 if (namelen > 1) 2062 return (ENOTDIR); 2063 if (namelen < 1) 2064 return (EINVAL); 2065 2066 pid = name[0]; 2067 if ((findpr = prfind(pid)) == NULL) 2068 return (ESRCH); 2069 2070 if (oldp == NULL) { 2071 *oldlenp = MAXPATHLEN * 4; 2072 return (0); 2073 } 2074 2075 /* Either system process or exiting/zombie */ 2076 if (findpr->ps_flags & (PS_SYSTEM | PS_EXITING)) 2077 return (EINVAL); 2078 2079 /* Only owner or root can get cwd */ 2080 if (findpr->ps_ucred->cr_uid != cp->p_ucred->cr_uid && 2081 (error = suser(cp)) != 0) 2082 return (error); 2083 2084 len = *oldlenp; 2085 if (len > MAXPATHLEN * 4) 2086 len = MAXPATHLEN * 4; 2087 else if (len < 2) 2088 return (ERANGE); 2089 *oldlenp = 0; 2090 2091 /* snag a reference to the vnode before we can sleep */ 2092 vp = findpr->ps_fd->fd_cdir; 2093 vref(vp); 2094 2095 path = malloc(len, M_TEMP, M_WAITOK); 2096 2097 bp = &path[len]; 2098 bend = bp; 2099 *(--bp) = '\0'; 2100 2101 /* Same as sys__getcwd */ 2102 error = vfs_getcwd_common(vp, NULL, 2103 &bp, path, len / 2, GETCWD_CHECK_ACCESS, cp); 2104 if (error == 0) { 2105 *oldlenp = lenused = bend - bp; 2106 error = copyout(bp, oldp, lenused); 2107 } 2108 2109 vrele(vp); 2110 free(path, M_TEMP, len); 2111 2112 return (error); 2113 } 2114 2115 int 2116 sysctl_proc_nobroadcastkill(int *name, u_int namelen, void *newp, size_t newlen, 2117 void *oldp, size_t *oldlenp, struct proc *cp) 2118 { 2119 struct process *findpr; 2120 pid_t pid; 2121 int error, flag; 2122 2123 if (namelen > 1) 2124 return (ENOTDIR); 2125 if (namelen < 1) 2126 return (EINVAL); 2127 2128 pid = name[0]; 2129 if ((findpr = prfind(pid)) == NULL) 2130 return (ESRCH); 2131 2132 /* Either system process or exiting/zombie */ 2133 if (findpr->ps_flags & (PS_SYSTEM | PS_EXITING)) 2134 return (EINVAL); 2135 2136 /* Only root can change PS_NOBROADCASTKILL */ 2137 if (newp != NULL && (error = suser(cp)) != 0) 2138 return (error); 2139 2140 /* get the PS_NOBROADCASTKILL flag */ 2141 flag = findpr->ps_flags & PS_NOBROADCASTKILL ? 1 : 0; 2142 2143 error = sysctl_int(oldp, oldlenp, newp, newlen, &flag); 2144 if (error == 0 && newp) { 2145 if (flag) 2146 atomic_setbits_int(&findpr->ps_flags, 2147 PS_NOBROADCASTKILL); 2148 else 2149 atomic_clearbits_int(&findpr->ps_flags, 2150 PS_NOBROADCASTKILL); 2151 } 2152 2153 return (error); 2154 } 2155 2156 /* Arbitrary but reasonable limit for one iteration. */ 2157 #define VMMAP_MAXLEN MAXPHYS 2158 2159 int 2160 sysctl_proc_vmmap(int *name, u_int namelen, void *oldp, size_t *oldlenp, 2161 struct proc *cp) 2162 { 2163 struct process *findpr; 2164 pid_t pid; 2165 int error; 2166 size_t oldlen, len; 2167 struct kinfo_vmentry *kve, *ukve; 2168 u_long *ustart, start; 2169 2170 if (namelen > 1) 2171 return (ENOTDIR); 2172 if (namelen < 1) 2173 return (EINVAL); 2174 2175 /* Provide max buffer length as hint. */ 2176 if (oldp == NULL) { 2177 if (oldlenp == NULL) 2178 return (EINVAL); 2179 else { 2180 *oldlenp = VMMAP_MAXLEN; 2181 return (0); 2182 } 2183 } 2184 2185 pid = name[0]; 2186 if (pid == cp->p_p->ps_pid) { 2187 /* Self process mapping. */ 2188 findpr = cp->p_p; 2189 } else if (pid > 0) { 2190 if ((findpr = prfind(pid)) == NULL) 2191 return (ESRCH); 2192 2193 /* Either system process or exiting/zombie */ 2194 if (findpr->ps_flags & (PS_SYSTEM | PS_EXITING)) 2195 return (EINVAL); 2196 2197 #if 1 2198 /* XXX Allow only root for now */ 2199 if ((error = suser(cp)) != 0) 2200 return (error); 2201 #else 2202 /* Only owner or root can get vmmap */ 2203 if (findpr->ps_ucred->cr_uid != cp->p_ucred->cr_uid && 2204 (error = suser(cp)) != 0) 2205 return (error); 2206 #endif 2207 } else { 2208 /* Only root can get kernel_map */ 2209 if ((error = suser(cp)) != 0) 2210 return (error); 2211 findpr = NULL; 2212 } 2213 2214 /* Check the given size. */ 2215 oldlen = *oldlenp; 2216 if (oldlen == 0 || oldlen % sizeof(*kve) != 0) 2217 return (EINVAL); 2218 2219 /* Deny huge allocation. */ 2220 if (oldlen > VMMAP_MAXLEN) 2221 return (EINVAL); 2222 2223 /* 2224 * Iterate from the given address passed as the first element's 2225 * kve_start via oldp. 2226 */ 2227 ukve = (struct kinfo_vmentry *)oldp; 2228 ustart = &ukve->kve_start; 2229 error = copyin(ustart, &start, sizeof(start)); 2230 if (error != 0) 2231 return (error); 2232 2233 /* Allocate wired memory to not block. */ 2234 kve = malloc(oldlen, M_TEMP, M_WAITOK); 2235 2236 /* Set the base address and read entries. */ 2237 kve[0].kve_start = start; 2238 len = oldlen; 2239 error = fill_vmmap(findpr, kve, &len); 2240 if (error != 0 && error != ENOMEM) 2241 goto done; 2242 if (len == 0) 2243 goto done; 2244 2245 KASSERT(len <= oldlen); 2246 KASSERT((len % sizeof(struct kinfo_vmentry)) == 0); 2247 2248 error = copyout(kve, oldp, len); 2249 2250 done: 2251 *oldlenp = len; 2252 2253 free(kve, M_TEMP, oldlen); 2254 2255 return (error); 2256 } 2257 #endif 2258 2259 /* 2260 * Initialize disknames/diskstats for export by sysctl. If update is set, 2261 * then we simply update the disk statistics information. 2262 */ 2263 int 2264 sysctl_diskinit(int update, struct proc *p) 2265 { 2266 struct diskstats *sdk; 2267 struct disk *dk; 2268 const char *duid; 2269 int error, changed = 0; 2270 2271 KERNEL_ASSERT_LOCKED(); 2272 2273 if ((error = rw_enter(&sysctl_disklock, RW_WRITE|RW_INTR)) != 0) 2274 return error; 2275 2276 /* Run in a loop, disks may change while malloc sleeps. */ 2277 while (disk_change) { 2278 int tlen; 2279 2280 disk_change = 0; 2281 2282 tlen = 0; 2283 TAILQ_FOREACH(dk, &disklist, dk_link) { 2284 if (dk->dk_name) 2285 tlen += strlen(dk->dk_name); 2286 tlen += 18; /* label uid + separators */ 2287 } 2288 tlen++; 2289 2290 /* 2291 * The sysctl_disklock ensures that no other process can 2292 * allocate disknames and diskstats while our malloc sleeps. 2293 */ 2294 free(disknames, M_SYSCTL, disknameslen); 2295 free(diskstats, M_SYSCTL, diskstatslen); 2296 diskstats = NULL; 2297 disknames = NULL; 2298 diskstats = mallocarray(disk_count, sizeof(struct diskstats), 2299 M_SYSCTL, M_WAITOK|M_ZERO); 2300 diskstatslen = disk_count * sizeof(struct diskstats); 2301 disknames = malloc(tlen, M_SYSCTL, M_WAITOK|M_ZERO); 2302 disknameslen = tlen; 2303 disknames[0] = '\0'; 2304 changed = 1; 2305 } 2306 2307 if (changed) { 2308 int l; 2309 2310 l = 0; 2311 sdk = diskstats; 2312 TAILQ_FOREACH(dk, &disklist, dk_link) { 2313 duid = NULL; 2314 if (dk->dk_label && !duid_iszero(dk->dk_label->d_uid)) 2315 duid = duid_format(dk->dk_label->d_uid); 2316 snprintf(disknames + l, disknameslen - l, "%s:%s,", 2317 dk->dk_name ? dk->dk_name : "", 2318 duid ? duid : ""); 2319 l += strlen(disknames + l); 2320 strlcpy(sdk->ds_name, dk->dk_name, 2321 sizeof(sdk->ds_name)); 2322 mtx_enter(&dk->dk_mtx); 2323 sdk->ds_busy = dk->dk_busy; 2324 sdk->ds_rxfer = dk->dk_rxfer; 2325 sdk->ds_wxfer = dk->dk_wxfer; 2326 sdk->ds_seek = dk->dk_seek; 2327 sdk->ds_rbytes = dk->dk_rbytes; 2328 sdk->ds_wbytes = dk->dk_wbytes; 2329 sdk->ds_attachtime = dk->dk_attachtime; 2330 sdk->ds_timestamp = dk->dk_timestamp; 2331 sdk->ds_time = dk->dk_time; 2332 mtx_leave(&dk->dk_mtx); 2333 sdk++; 2334 } 2335 2336 /* Eliminate trailing comma */ 2337 if (l != 0) 2338 disknames[l - 1] = '\0'; 2339 } else if (update) { 2340 /* Just update, number of drives hasn't changed */ 2341 sdk = diskstats; 2342 TAILQ_FOREACH(dk, &disklist, dk_link) { 2343 strlcpy(sdk->ds_name, dk->dk_name, 2344 sizeof(sdk->ds_name)); 2345 mtx_enter(&dk->dk_mtx); 2346 sdk->ds_busy = dk->dk_busy; 2347 sdk->ds_rxfer = dk->dk_rxfer; 2348 sdk->ds_wxfer = dk->dk_wxfer; 2349 sdk->ds_seek = dk->dk_seek; 2350 sdk->ds_rbytes = dk->dk_rbytes; 2351 sdk->ds_wbytes = dk->dk_wbytes; 2352 sdk->ds_attachtime = dk->dk_attachtime; 2353 sdk->ds_timestamp = dk->dk_timestamp; 2354 sdk->ds_time = dk->dk_time; 2355 mtx_leave(&dk->dk_mtx); 2356 sdk++; 2357 } 2358 } 2359 rw_exit_write(&sysctl_disklock); 2360 return 0; 2361 } 2362 2363 #if defined(SYSVMSG) || defined(SYSVSEM) || defined(SYSVSHM) 2364 int 2365 sysctl_sysvipc(int *name, u_int namelen, void *where, size_t *sizep) 2366 { 2367 #ifdef SYSVSEM 2368 struct sem_sysctl_info *semsi; 2369 #endif 2370 #ifdef SYSVSHM 2371 struct shm_sysctl_info *shmsi; 2372 #endif 2373 size_t infosize, dssize, tsize, buflen, bufsiz; 2374 int i, nds, error, ret; 2375 void *buf; 2376 2377 if (namelen != 1) 2378 return (EINVAL); 2379 2380 buflen = *sizep; 2381 2382 switch (*name) { 2383 case KERN_SYSVIPC_MSG_INFO: 2384 #ifdef SYSVMSG 2385 return (sysctl_sysvmsg(name, namelen, where, sizep)); 2386 #else 2387 return (EOPNOTSUPP); 2388 #endif 2389 case KERN_SYSVIPC_SEM_INFO: 2390 #ifdef SYSVSEM 2391 infosize = sizeof(semsi->seminfo); 2392 nds = seminfo.semmni; 2393 dssize = sizeof(semsi->semids[0]); 2394 break; 2395 #else 2396 return (EOPNOTSUPP); 2397 #endif 2398 case KERN_SYSVIPC_SHM_INFO: 2399 #ifdef SYSVSHM 2400 infosize = sizeof(shmsi->shminfo); 2401 nds = shminfo.shmmni; 2402 dssize = sizeof(shmsi->shmids[0]); 2403 break; 2404 #else 2405 return (EOPNOTSUPP); 2406 #endif 2407 default: 2408 return (EINVAL); 2409 } 2410 tsize = infosize + (nds * dssize); 2411 2412 /* Return just the total size required. */ 2413 if (where == NULL) { 2414 *sizep = tsize; 2415 return (0); 2416 } 2417 2418 /* Not enough room for even the info struct. */ 2419 if (buflen < infosize) { 2420 *sizep = 0; 2421 return (ENOMEM); 2422 } 2423 bufsiz = min(tsize, buflen); 2424 buf = malloc(bufsiz, M_TEMP, M_WAITOK|M_ZERO); 2425 2426 switch (*name) { 2427 #ifdef SYSVSEM 2428 case KERN_SYSVIPC_SEM_INFO: 2429 semsi = (struct sem_sysctl_info *)buf; 2430 semsi->seminfo = seminfo; 2431 break; 2432 #endif 2433 #ifdef SYSVSHM 2434 case KERN_SYSVIPC_SHM_INFO: 2435 shmsi = (struct shm_sysctl_info *)buf; 2436 shmsi->shminfo = shminfo; 2437 break; 2438 #endif 2439 } 2440 buflen -= infosize; 2441 2442 ret = 0; 2443 if (buflen > 0) { 2444 /* Fill in the IPC data structures. */ 2445 for (i = 0; i < nds; i++) { 2446 if (buflen < dssize) { 2447 ret = ENOMEM; 2448 break; 2449 } 2450 switch (*name) { 2451 #ifdef SYSVSEM 2452 case KERN_SYSVIPC_SEM_INFO: 2453 if (sema[i] != NULL) 2454 memcpy(&semsi->semids[i], sema[i], 2455 dssize); 2456 else 2457 memset(&semsi->semids[i], 0, dssize); 2458 break; 2459 #endif 2460 #ifdef SYSVSHM 2461 case KERN_SYSVIPC_SHM_INFO: 2462 if (shmsegs[i] != NULL) 2463 memcpy(&shmsi->shmids[i], shmsegs[i], 2464 dssize); 2465 else 2466 memset(&shmsi->shmids[i], 0, dssize); 2467 break; 2468 #endif 2469 } 2470 buflen -= dssize; 2471 } 2472 } 2473 *sizep -= buflen; 2474 error = copyout(buf, where, *sizep); 2475 free(buf, M_TEMP, bufsiz); 2476 /* If copyout succeeded, use return code set earlier. */ 2477 return (error ? error : ret); 2478 } 2479 #endif /* SYSVMSG || SYSVSEM || SYSVSHM */ 2480 2481 #ifndef SMALL_KERNEL 2482 2483 int 2484 sysctl_intrcnt(int *name, u_int namelen, void *oldp, size_t *oldlenp) 2485 { 2486 return (evcount_sysctl(name, namelen, oldp, oldlenp, NULL, 0)); 2487 } 2488 2489 2490 int 2491 sysctl_sensors(int *name, u_int namelen, void *oldp, size_t *oldlenp, 2492 void *newp, size_t newlen) 2493 { 2494 struct ksensor *ks; 2495 struct sensor *us; 2496 struct ksensordev *ksd; 2497 struct sensordev *usd; 2498 int dev, numt, ret; 2499 enum sensor_type type; 2500 2501 if (namelen != 1 && namelen != 3) 2502 return (ENOTDIR); 2503 2504 dev = name[0]; 2505 if (namelen == 1) { 2506 ret = sensordev_get(dev, &ksd); 2507 if (ret) 2508 return (ret); 2509 2510 /* Grab a copy, to clear the kernel pointers */ 2511 usd = malloc(sizeof(*usd), M_TEMP, M_WAITOK|M_ZERO); 2512 usd->num = ksd->num; 2513 strlcpy(usd->xname, ksd->xname, sizeof(usd->xname)); 2514 memcpy(usd->maxnumt, ksd->maxnumt, sizeof(usd->maxnumt)); 2515 usd->sensors_count = ksd->sensors_count; 2516 2517 ret = sysctl_rdstruct(oldp, oldlenp, newp, usd, 2518 sizeof(struct sensordev)); 2519 2520 free(usd, M_TEMP, sizeof(*usd)); 2521 return (ret); 2522 } 2523 2524 type = name[1]; 2525 numt = name[2]; 2526 2527 ret = sensor_find(dev, type, numt, &ks); 2528 if (ret) 2529 return (ret); 2530 2531 /* Grab a copy, to clear the kernel pointers */ 2532 us = malloc(sizeof(*us), M_TEMP, M_WAITOK|M_ZERO); 2533 memcpy(us->desc, ks->desc, sizeof(us->desc)); 2534 us->tv = ks->tv; 2535 us->value = ks->value; 2536 us->type = ks->type; 2537 us->status = ks->status; 2538 us->numt = ks->numt; 2539 us->flags = ks->flags; 2540 2541 ret = sysctl_rdstruct(oldp, oldlenp, newp, us, 2542 sizeof(struct sensor)); 2543 free(us, M_TEMP, sizeof(*us)); 2544 return (ret); 2545 } 2546 #endif /* SMALL_KERNEL */ 2547 2548 int 2549 sysctl_cptime2(int *name, u_int namelen, void *oldp, size_t *oldlenp, 2550 void *newp, size_t newlen) 2551 { 2552 CPU_INFO_ITERATOR cii; 2553 struct cpu_info *ci; 2554 int found = 0; 2555 2556 if (namelen != 1) 2557 return (ENOTDIR); 2558 2559 CPU_INFO_FOREACH(cii, ci) { 2560 if (name[0] == CPU_INFO_UNIT(ci)) { 2561 found = 1; 2562 break; 2563 } 2564 } 2565 if (!found) 2566 return (ENOENT); 2567 2568 return (sysctl_rdstruct(oldp, oldlenp, newp, 2569 &ci->ci_schedstate.spc_cp_time, 2570 sizeof(ci->ci_schedstate.spc_cp_time))); 2571 } 2572 2573 #if NAUDIO > 0 2574 int 2575 sysctl_audio(int *name, u_int namelen, void *oldp, size_t *oldlenp, 2576 void *newp, size_t newlen) 2577 { 2578 if (namelen != 1) 2579 return (ENOTDIR); 2580 2581 if (name[0] != KERN_AUDIO_RECORD) 2582 return (ENOENT); 2583 2584 return (sysctl_int(oldp, oldlenp, newp, newlen, &audio_record_enable)); 2585 } 2586 #endif 2587 2588 #if NVIDEO > 0 2589 int 2590 sysctl_video(int *name, u_int namelen, void *oldp, size_t *oldlenp, 2591 void *newp, size_t newlen) 2592 { 2593 if (namelen != 1) 2594 return (ENOTDIR); 2595 2596 if (name[0] != KERN_VIDEO_RECORD) 2597 return (ENOENT); 2598 2599 return (sysctl_int(oldp, oldlenp, newp, newlen, &video_record_enable)); 2600 } 2601 #endif 2602 2603 int 2604 sysctl_cpustats(int *name, u_int namelen, void *oldp, size_t *oldlenp, 2605 void *newp, size_t newlen) 2606 { 2607 CPU_INFO_ITERATOR cii; 2608 struct cpustats cs; 2609 struct cpu_info *ci; 2610 int found = 0; 2611 2612 if (namelen != 1) 2613 return (ENOTDIR); 2614 2615 CPU_INFO_FOREACH(cii, ci) { 2616 if (name[0] == CPU_INFO_UNIT(ci)) { 2617 found = 1; 2618 break; 2619 } 2620 } 2621 if (!found) 2622 return (ENOENT); 2623 2624 memset(&cs, 0, sizeof cs); 2625 memcpy(&cs.cs_time, &ci->ci_schedstate.spc_cp_time, sizeof(cs.cs_time)); 2626 cs.cs_flags = 0; 2627 if (cpu_is_online(ci)) 2628 cs.cs_flags |= CPUSTATS_ONLINE; 2629 2630 return (sysctl_rdstruct(oldp, oldlenp, newp, &cs, sizeof(cs))); 2631 } 2632 2633 int 2634 sysctl_utc_offset(void *oldp, size_t *oldlenp, void *newp, size_t newlen) 2635 { 2636 struct timespec adjusted, now; 2637 int adjustment_seconds, error, new_offset_minutes, old_offset_minutes; 2638 2639 old_offset_minutes = utc_offset / 60; /* seconds -> minutes */ 2640 new_offset_minutes = old_offset_minutes; 2641 error = sysctl_securelevel_int(oldp, oldlenp, newp, newlen, 2642 &new_offset_minutes); 2643 if (error) 2644 return error; 2645 if (new_offset_minutes < -24 * 60 || new_offset_minutes > 24 * 60) 2646 return EINVAL; 2647 if (new_offset_minutes == old_offset_minutes) 2648 return 0; 2649 2650 utc_offset = new_offset_minutes * 60; /* minutes -> seconds */ 2651 adjustment_seconds = (new_offset_minutes - old_offset_minutes) * 60; 2652 2653 nanotime(&now); 2654 adjusted = now; 2655 adjusted.tv_sec -= adjustment_seconds; 2656 tc_setrealtimeclock(&adjusted); 2657 resettodr(); 2658 2659 return 0; 2660 } 2661