1 /* $OpenBSD: kern_sysctl.c,v 1.420 2023/10/01 15:58:12 krw 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 switch (so->so_proto->pr_domain->dom_family) { 1287 case AF_INET: 1288 case AF_INET6: 1289 NET_LOCK(); 1290 locked = 1; 1291 break; 1292 } 1293 } 1294 1295 kf->so_type = so->so_type; 1296 kf->so_state = so->so_state | so->so_snd.sb_state | 1297 so->so_rcv.sb_state; 1298 if (show_pointers) 1299 kf->so_pcb = PTRTOINT64(so->so_pcb); 1300 else 1301 kf->so_pcb = -1; 1302 kf->so_protocol = so->so_proto->pr_protocol; 1303 kf->so_family = so->so_proto->pr_domain->dom_family; 1304 kf->so_rcv_cc = so->so_rcv.sb_cc; 1305 kf->so_snd_cc = so->so_snd.sb_cc; 1306 if (isspliced(so)) { 1307 if (show_pointers) 1308 kf->so_splice = 1309 PTRTOINT64(so->so_sp->ssp_socket); 1310 kf->so_splicelen = so->so_sp->ssp_len; 1311 } else if (issplicedback(so)) 1312 kf->so_splicelen = -1; 1313 if (so->so_pcb == NULL) { 1314 if (locked) 1315 NET_UNLOCK(); 1316 break; 1317 } 1318 switch (kf->so_family) { 1319 case AF_INET: { 1320 struct inpcb *inpcb = so->so_pcb; 1321 1322 NET_ASSERT_LOCKED(); 1323 if (show_pointers) 1324 kf->inp_ppcb = PTRTOINT64(inpcb->inp_ppcb); 1325 kf->inp_lport = inpcb->inp_lport; 1326 kf->inp_laddru[0] = inpcb->inp_laddr.s_addr; 1327 kf->inp_fport = inpcb->inp_fport; 1328 kf->inp_faddru[0] = inpcb->inp_faddr.s_addr; 1329 kf->inp_rtableid = inpcb->inp_rtableid; 1330 if (so->so_type == SOCK_RAW) 1331 kf->inp_proto = inpcb->inp_ip.ip_p; 1332 if (so->so_proto->pr_protocol == IPPROTO_TCP) { 1333 struct tcpcb *tcpcb = (void *)inpcb->inp_ppcb; 1334 kf->t_rcv_wnd = tcpcb->rcv_wnd; 1335 kf->t_snd_wnd = tcpcb->snd_wnd; 1336 kf->t_snd_cwnd = tcpcb->snd_cwnd; 1337 kf->t_state = tcpcb->t_state; 1338 } 1339 break; 1340 } 1341 case AF_INET6: { 1342 struct inpcb *inpcb = so->so_pcb; 1343 1344 NET_ASSERT_LOCKED(); 1345 if (show_pointers) 1346 kf->inp_ppcb = PTRTOINT64(inpcb->inp_ppcb); 1347 kf->inp_lport = inpcb->inp_lport; 1348 kf->inp_laddru[0] = inpcb->inp_laddr6.s6_addr32[0]; 1349 kf->inp_laddru[1] = inpcb->inp_laddr6.s6_addr32[1]; 1350 kf->inp_laddru[2] = inpcb->inp_laddr6.s6_addr32[2]; 1351 kf->inp_laddru[3] = inpcb->inp_laddr6.s6_addr32[3]; 1352 kf->inp_fport = inpcb->inp_fport; 1353 kf->inp_faddru[0] = inpcb->inp_faddr6.s6_addr32[0]; 1354 kf->inp_faddru[1] = inpcb->inp_faddr6.s6_addr32[1]; 1355 kf->inp_faddru[2] = inpcb->inp_faddr6.s6_addr32[2]; 1356 kf->inp_faddru[3] = inpcb->inp_faddr6.s6_addr32[3]; 1357 kf->inp_rtableid = inpcb->inp_rtableid; 1358 if (so->so_type == SOCK_RAW) 1359 kf->inp_proto = inpcb->inp_ipv6.ip6_nxt; 1360 if (so->so_proto->pr_protocol == IPPROTO_TCP) { 1361 struct tcpcb *tcpcb = (void *)inpcb->inp_ppcb; 1362 kf->t_rcv_wnd = tcpcb->rcv_wnd; 1363 kf->t_snd_wnd = tcpcb->snd_wnd; 1364 kf->t_state = tcpcb->t_state; 1365 } 1366 break; 1367 } 1368 case AF_UNIX: { 1369 struct unpcb *unpcb = so->so_pcb; 1370 1371 kf->f_msgcount = unpcb->unp_msgcount; 1372 if (show_pointers) { 1373 kf->unp_conn = PTRTOINT64(unpcb->unp_conn); 1374 kf->unp_refs = PTRTOINT64( 1375 SLIST_FIRST(&unpcb->unp_refs)); 1376 kf->unp_nextref = PTRTOINT64( 1377 SLIST_NEXT(unpcb, unp_nextref)); 1378 kf->v_un = PTRTOINT64(unpcb->unp_vnode); 1379 kf->unp_addr = PTRTOINT64(unpcb->unp_addr); 1380 } 1381 if (unpcb->unp_addr != NULL) { 1382 struct sockaddr_un *un = mtod(unpcb->unp_addr, 1383 struct sockaddr_un *); 1384 memcpy(kf->unp_path, un->sun_path, un->sun_len 1385 - offsetof(struct sockaddr_un,sun_path)); 1386 } 1387 break; 1388 } 1389 } 1390 if (locked) 1391 NET_UNLOCK(); 1392 break; 1393 } 1394 1395 case DTYPE_PIPE: { 1396 struct pipe *pipe = (struct pipe *)fp->f_data; 1397 1398 if (show_pointers) 1399 kf->pipe_peer = PTRTOINT64(pipe->pipe_peer); 1400 kf->pipe_state = pipe->pipe_state; 1401 break; 1402 } 1403 1404 case DTYPE_KQUEUE: { 1405 struct kqueue *kqi = (struct kqueue *)fp->f_data; 1406 1407 kf->kq_count = kqi->kq_count; 1408 kf->kq_state = kqi->kq_state; 1409 break; 1410 } 1411 } 1412 1413 /* per-process information for KERN_FILE_BY[PU]ID */ 1414 if (pr != NULL) { 1415 kf->p_pid = pr->ps_pid; 1416 kf->p_uid = pr->ps_ucred->cr_uid; 1417 kf->p_gid = pr->ps_ucred->cr_gid; 1418 kf->p_tid = -1; 1419 strlcpy(kf->p_comm, pr->ps_comm, sizeof(kf->p_comm)); 1420 } 1421 if (fdp != NULL) { 1422 fdplock(fdp); 1423 kf->fd_ofileflags = fdp->fd_ofileflags[fd]; 1424 fdpunlock(fdp); 1425 } 1426 } 1427 1428 /* 1429 * Get file structures. 1430 */ 1431 int 1432 sysctl_file(int *name, u_int namelen, char *where, size_t *sizep, 1433 struct proc *p) 1434 { 1435 struct kinfo_file *kf; 1436 struct filedesc *fdp; 1437 struct file *fp; 1438 struct process *pr; 1439 size_t buflen, elem_size, elem_count, outsize; 1440 char *dp = where; 1441 int arg, i, error = 0, needed = 0, matched; 1442 u_int op; 1443 int show_pointers; 1444 1445 if (namelen > 4) 1446 return (ENOTDIR); 1447 if (namelen < 4 || name[2] > sizeof(*kf)) 1448 return (EINVAL); 1449 1450 buflen = where != NULL ? *sizep : 0; 1451 op = name[0]; 1452 arg = name[1]; 1453 elem_size = name[2]; 1454 elem_count = name[3]; 1455 outsize = MIN(sizeof(*kf), elem_size); 1456 1457 if (elem_size < 1) 1458 return (EINVAL); 1459 1460 show_pointers = suser(curproc) == 0; 1461 1462 kf = malloc(sizeof(*kf), M_TEMP, M_WAITOK); 1463 1464 #define FILLIT2(fp, fdp, i, vp, pr, so) do { \ 1465 if (buflen >= elem_size && elem_count > 0) { \ 1466 fill_file(kf, fp, fdp, i, vp, pr, p, so, show_pointers);\ 1467 error = copyout(kf, dp, outsize); \ 1468 if (error) \ 1469 break; \ 1470 dp += elem_size; \ 1471 buflen -= elem_size; \ 1472 elem_count--; \ 1473 } \ 1474 needed += elem_size; \ 1475 } while (0) 1476 #define FILLIT(fp, fdp, i, vp, pr) \ 1477 FILLIT2(fp, fdp, i, vp, pr, NULL) 1478 #define FILLSO(so) \ 1479 FILLIT2(NULL, NULL, 0, NULL, NULL, so) 1480 1481 switch (op) { 1482 case KERN_FILE_BYFILE: 1483 /* use the inp-tables to pick up closed connections, too */ 1484 if (arg == DTYPE_SOCKET) { 1485 struct inpcb *inp; 1486 1487 NET_LOCK(); 1488 mtx_enter(&tcbtable.inpt_mtx); 1489 TAILQ_FOREACH(inp, &tcbtable.inpt_queue, inp_queue) 1490 FILLSO(inp->inp_socket); 1491 mtx_leave(&tcbtable.inpt_mtx); 1492 mtx_enter(&udbtable.inpt_mtx); 1493 TAILQ_FOREACH(inp, &udbtable.inpt_queue, inp_queue) 1494 FILLSO(inp->inp_socket); 1495 mtx_leave(&udbtable.inpt_mtx); 1496 mtx_enter(&rawcbtable.inpt_mtx); 1497 TAILQ_FOREACH(inp, &rawcbtable.inpt_queue, inp_queue) 1498 FILLSO(inp->inp_socket); 1499 mtx_leave(&rawcbtable.inpt_mtx); 1500 #ifdef INET6 1501 mtx_enter(&rawin6pcbtable.inpt_mtx); 1502 TAILQ_FOREACH(inp, &rawin6pcbtable.inpt_queue, 1503 inp_queue) 1504 FILLSO(inp->inp_socket); 1505 mtx_leave(&rawin6pcbtable.inpt_mtx); 1506 #endif 1507 NET_UNLOCK(); 1508 } 1509 fp = NULL; 1510 while ((fp = fd_iterfile(fp, p)) != NULL) { 1511 if ((arg == 0 || fp->f_type == arg)) { 1512 int af, skip = 0; 1513 if (arg == DTYPE_SOCKET && fp->f_type == arg) { 1514 af = ((struct socket *)fp->f_data)-> 1515 so_proto->pr_domain->dom_family; 1516 if (af == AF_INET || af == AF_INET6) 1517 skip = 1; 1518 } 1519 if (!skip) 1520 FILLIT(fp, NULL, 0, NULL, NULL); 1521 } 1522 } 1523 break; 1524 case KERN_FILE_BYPID: 1525 /* A arg of -1 indicates all processes */ 1526 if (arg < -1) { 1527 error = EINVAL; 1528 break; 1529 } 1530 matched = 0; 1531 LIST_FOREACH(pr, &allprocess, ps_list) { 1532 /* 1533 * skip system, exiting, embryonic and undead 1534 * processes 1535 */ 1536 if (pr->ps_flags & (PS_SYSTEM | PS_EMBRYO | PS_EXITING)) 1537 continue; 1538 if (arg > 0 && pr->ps_pid != (pid_t)arg) { 1539 /* not the pid we are looking for */ 1540 continue; 1541 } 1542 matched = 1; 1543 fdp = pr->ps_fd; 1544 if (pr->ps_textvp) 1545 FILLIT(NULL, NULL, KERN_FILE_TEXT, pr->ps_textvp, pr); 1546 if (fdp->fd_cdir) 1547 FILLIT(NULL, NULL, KERN_FILE_CDIR, fdp->fd_cdir, pr); 1548 if (fdp->fd_rdir) 1549 FILLIT(NULL, NULL, KERN_FILE_RDIR, fdp->fd_rdir, pr); 1550 if (pr->ps_tracevp) 1551 FILLIT(NULL, NULL, KERN_FILE_TRACE, pr->ps_tracevp, pr); 1552 for (i = 0; i < fdp->fd_nfiles; i++) { 1553 if ((fp = fd_getfile(fdp, i)) == NULL) 1554 continue; 1555 FILLIT(fp, fdp, i, NULL, pr); 1556 FRELE(fp, p); 1557 } 1558 } 1559 if (!matched) 1560 error = ESRCH; 1561 break; 1562 case KERN_FILE_BYUID: 1563 LIST_FOREACH(pr, &allprocess, ps_list) { 1564 /* 1565 * skip system, exiting, embryonic and undead 1566 * processes 1567 */ 1568 if (pr->ps_flags & (PS_SYSTEM | PS_EMBRYO | PS_EXITING)) 1569 continue; 1570 if (arg >= 0 && pr->ps_ucred->cr_uid != (uid_t)arg) { 1571 /* not the uid we are looking for */ 1572 continue; 1573 } 1574 fdp = pr->ps_fd; 1575 if (fdp->fd_cdir) 1576 FILLIT(NULL, NULL, KERN_FILE_CDIR, fdp->fd_cdir, pr); 1577 if (fdp->fd_rdir) 1578 FILLIT(NULL, NULL, KERN_FILE_RDIR, fdp->fd_rdir, pr); 1579 if (pr->ps_tracevp) 1580 FILLIT(NULL, NULL, KERN_FILE_TRACE, pr->ps_tracevp, pr); 1581 for (i = 0; i < fdp->fd_nfiles; i++) { 1582 if ((fp = fd_getfile(fdp, i)) == NULL) 1583 continue; 1584 FILLIT(fp, fdp, i, NULL, pr); 1585 FRELE(fp, p); 1586 } 1587 } 1588 break; 1589 default: 1590 error = EINVAL; 1591 break; 1592 } 1593 free(kf, M_TEMP, sizeof(*kf)); 1594 1595 if (!error) { 1596 if (where == NULL) 1597 needed += KERN_FILESLOP * elem_size; 1598 else if (*sizep < needed) 1599 error = ENOMEM; 1600 *sizep = needed; 1601 } 1602 1603 return (error); 1604 } 1605 1606 /* 1607 * try over estimating by 5 procs 1608 */ 1609 #define KERN_PROCSLOP 5 1610 1611 int 1612 sysctl_doproc(int *name, u_int namelen, char *where, size_t *sizep) 1613 { 1614 struct kinfo_proc *kproc = NULL; 1615 struct proc *p; 1616 struct process *pr; 1617 char *dp; 1618 int arg, buflen, doingzomb, elem_size, elem_count; 1619 int error, needed, op; 1620 int dothreads = 0; 1621 int show_pointers; 1622 1623 dp = where; 1624 buflen = where != NULL ? *sizep : 0; 1625 needed = error = 0; 1626 1627 if (namelen != 4 || name[2] <= 0 || name[3] < 0 || 1628 name[2] > sizeof(*kproc)) 1629 return (EINVAL); 1630 op = name[0]; 1631 arg = name[1]; 1632 elem_size = name[2]; 1633 elem_count = name[3]; 1634 1635 dothreads = op & KERN_PROC_SHOW_THREADS; 1636 op &= ~KERN_PROC_SHOW_THREADS; 1637 1638 show_pointers = suser(curproc) == 0; 1639 1640 if (where != NULL) 1641 kproc = malloc(sizeof(*kproc), M_TEMP, M_WAITOK); 1642 1643 pr = LIST_FIRST(&allprocess); 1644 doingzomb = 0; 1645 again: 1646 for (; pr != NULL; pr = LIST_NEXT(pr, ps_list)) { 1647 /* XXX skip processes in the middle of being zapped */ 1648 if (pr->ps_pgrp == NULL) 1649 continue; 1650 1651 /* 1652 * Skip embryonic processes. 1653 */ 1654 if (pr->ps_flags & PS_EMBRYO) 1655 continue; 1656 1657 /* 1658 * TODO - make more efficient (see notes below). 1659 */ 1660 switch (op) { 1661 1662 case KERN_PROC_PID: 1663 /* could do this with just a lookup */ 1664 if (pr->ps_pid != (pid_t)arg) 1665 continue; 1666 break; 1667 1668 case KERN_PROC_PGRP: 1669 /* could do this by traversing pgrp */ 1670 if (pr->ps_pgrp->pg_id != (pid_t)arg) 1671 continue; 1672 break; 1673 1674 case KERN_PROC_SESSION: 1675 if (pr->ps_session->s_leader == NULL || 1676 pr->ps_session->s_leader->ps_pid != (pid_t)arg) 1677 continue; 1678 break; 1679 1680 case KERN_PROC_TTY: 1681 if ((pr->ps_flags & PS_CONTROLT) == 0 || 1682 pr->ps_session->s_ttyp == NULL || 1683 pr->ps_session->s_ttyp->t_dev != (dev_t)arg) 1684 continue; 1685 break; 1686 1687 case KERN_PROC_UID: 1688 if (pr->ps_ucred->cr_uid != (uid_t)arg) 1689 continue; 1690 break; 1691 1692 case KERN_PROC_RUID: 1693 if (pr->ps_ucred->cr_ruid != (uid_t)arg) 1694 continue; 1695 break; 1696 1697 case KERN_PROC_ALL: 1698 if (pr->ps_flags & PS_SYSTEM) 1699 continue; 1700 break; 1701 1702 case KERN_PROC_KTHREAD: 1703 /* no filtering */ 1704 break; 1705 1706 default: 1707 error = EINVAL; 1708 goto err; 1709 } 1710 1711 if (buflen >= elem_size && elem_count > 0) { 1712 fill_kproc(pr, kproc, NULL, show_pointers); 1713 error = copyout(kproc, dp, elem_size); 1714 if (error) 1715 goto err; 1716 dp += elem_size; 1717 buflen -= elem_size; 1718 elem_count--; 1719 } 1720 needed += elem_size; 1721 1722 /* Skip per-thread entries if not required by op */ 1723 if (!dothreads) 1724 continue; 1725 1726 TAILQ_FOREACH(p, &pr->ps_threads, p_thr_link) { 1727 if (buflen >= elem_size && elem_count > 0) { 1728 fill_kproc(pr, kproc, p, show_pointers); 1729 error = copyout(kproc, dp, elem_size); 1730 if (error) 1731 goto err; 1732 dp += elem_size; 1733 buflen -= elem_size; 1734 elem_count--; 1735 } 1736 needed += elem_size; 1737 } 1738 } 1739 if (doingzomb == 0) { 1740 pr = LIST_FIRST(&zombprocess); 1741 doingzomb++; 1742 goto again; 1743 } 1744 if (where != NULL) { 1745 *sizep = dp - where; 1746 if (needed > *sizep) { 1747 error = ENOMEM; 1748 goto err; 1749 } 1750 } else { 1751 needed += KERN_PROCSLOP * elem_size; 1752 *sizep = needed; 1753 } 1754 err: 1755 if (kproc) 1756 free(kproc, M_TEMP, sizeof(*kproc)); 1757 return (error); 1758 } 1759 1760 /* 1761 * Fill in a kproc structure for the specified process. 1762 */ 1763 void 1764 fill_kproc(struct process *pr, struct kinfo_proc *ki, struct proc *p, 1765 int show_pointers) 1766 { 1767 struct session *s = pr->ps_session; 1768 struct tty *tp; 1769 struct vmspace *vm = pr->ps_vmspace; 1770 struct timespec booted, st, ut, utc; 1771 int isthread; 1772 1773 isthread = p != NULL; 1774 if (!isthread) 1775 p = pr->ps_mainproc; /* XXX */ 1776 1777 FILL_KPROC(ki, strlcpy, p, pr, pr->ps_ucred, pr->ps_pgrp, 1778 p, pr, s, vm, pr->ps_limit, pr->ps_sigacts, isthread, 1779 show_pointers); 1780 1781 /* stuff that's too painful to generalize into the macros */ 1782 if (pr->ps_pptr) 1783 ki->p_ppid = pr->ps_ppid; 1784 if (s->s_leader) 1785 ki->p_sid = s->s_leader->ps_pid; 1786 1787 if ((pr->ps_flags & PS_CONTROLT) && (tp = s->s_ttyp)) { 1788 ki->p_tdev = tp->t_dev; 1789 ki->p_tpgid = tp->t_pgrp ? tp->t_pgrp->pg_id : -1; 1790 if (show_pointers) 1791 ki->p_tsess = PTRTOINT64(tp->t_session); 1792 } else { 1793 ki->p_tdev = NODEV; 1794 ki->p_tpgid = -1; 1795 } 1796 1797 /* fixups that can only be done in the kernel */ 1798 if ((pr->ps_flags & PS_ZOMBIE) == 0) { 1799 if ((pr->ps_flags & PS_EMBRYO) == 0 && vm != NULL) 1800 ki->p_vm_rssize = vm_resident_count(vm); 1801 calctsru(isthread ? &p->p_tu : &pr->ps_tu, &ut, &st, NULL); 1802 ki->p_uutime_sec = ut.tv_sec; 1803 ki->p_uutime_usec = ut.tv_nsec/1000; 1804 ki->p_ustime_sec = st.tv_sec; 1805 ki->p_ustime_usec = st.tv_nsec/1000; 1806 1807 /* Convert starting uptime to a starting UTC time. */ 1808 nanoboottime(&booted); 1809 timespecadd(&booted, &pr->ps_start, &utc); 1810 ki->p_ustart_sec = utc.tv_sec; 1811 ki->p_ustart_usec = utc.tv_nsec / 1000; 1812 1813 #ifdef MULTIPROCESSOR 1814 if (p->p_cpu != NULL) 1815 ki->p_cpuid = CPU_INFO_UNIT(p->p_cpu); 1816 #endif 1817 } 1818 1819 /* get %cpu and schedule state: just one thread or sum of all? */ 1820 if (isthread) { 1821 ki->p_pctcpu = p->p_pctcpu; 1822 ki->p_stat = p->p_stat; 1823 } else { 1824 ki->p_pctcpu = 0; 1825 ki->p_stat = (pr->ps_flags & PS_ZOMBIE) ? SDEAD : SIDL; 1826 TAILQ_FOREACH(p, &pr->ps_threads, p_thr_link) { 1827 ki->p_pctcpu += p->p_pctcpu; 1828 /* find best state: ONPROC > RUN > STOP > SLEEP > .. */ 1829 if (p->p_stat == SONPROC || ki->p_stat == SONPROC) 1830 ki->p_stat = SONPROC; 1831 else if (p->p_stat == SRUN || ki->p_stat == SRUN) 1832 ki->p_stat = SRUN; 1833 else if (p->p_stat == SSTOP || ki->p_stat == SSTOP) 1834 ki->p_stat = SSTOP; 1835 else if (p->p_stat == SSLEEP) 1836 ki->p_stat = SSLEEP; 1837 } 1838 } 1839 } 1840 1841 int 1842 sysctl_proc_args(int *name, u_int namelen, void *oldp, size_t *oldlenp, 1843 struct proc *cp) 1844 { 1845 struct process *vpr; 1846 pid_t pid; 1847 struct ps_strings pss; 1848 struct iovec iov; 1849 struct uio uio; 1850 int error, cnt, op; 1851 size_t limit; 1852 char **rargv, **vargv; /* reader vs. victim */ 1853 char *rarg, *varg, *buf; 1854 struct vmspace *vm; 1855 vaddr_t ps_strings; 1856 1857 if (namelen > 2) 1858 return (ENOTDIR); 1859 if (namelen < 2) 1860 return (EINVAL); 1861 1862 pid = name[0]; 1863 op = name[1]; 1864 1865 switch (op) { 1866 case KERN_PROC_ARGV: 1867 case KERN_PROC_NARGV: 1868 case KERN_PROC_ENV: 1869 case KERN_PROC_NENV: 1870 break; 1871 default: 1872 return (EOPNOTSUPP); 1873 } 1874 1875 if ((vpr = prfind(pid)) == NULL) 1876 return (ESRCH); 1877 1878 if (oldp == NULL) { 1879 if (op == KERN_PROC_NARGV || op == KERN_PROC_NENV) 1880 *oldlenp = sizeof(int); 1881 else 1882 *oldlenp = ARG_MAX; /* XXX XXX XXX */ 1883 return (0); 1884 } 1885 1886 /* Either system process or exiting/zombie */ 1887 if (vpr->ps_flags & (PS_SYSTEM | PS_EXITING)) 1888 return (EINVAL); 1889 1890 /* Execing - danger. */ 1891 if ((vpr->ps_flags & PS_INEXEC)) 1892 return (EBUSY); 1893 1894 /* Only owner or root can get env */ 1895 if ((op == KERN_PROC_NENV || op == KERN_PROC_ENV) && 1896 (vpr->ps_ucred->cr_uid != cp->p_ucred->cr_uid && 1897 (error = suser(cp)) != 0)) 1898 return (error); 1899 1900 ps_strings = vpr->ps_strings; 1901 vm = vpr->ps_vmspace; 1902 uvmspace_addref(vm); 1903 vpr = NULL; 1904 1905 buf = malloc(PAGE_SIZE, M_TEMP, M_WAITOK); 1906 1907 iov.iov_base = &pss; 1908 iov.iov_len = sizeof(pss); 1909 uio.uio_iov = &iov; 1910 uio.uio_iovcnt = 1; 1911 uio.uio_offset = (off_t)ps_strings; 1912 uio.uio_resid = sizeof(pss); 1913 uio.uio_segflg = UIO_SYSSPACE; 1914 uio.uio_rw = UIO_READ; 1915 uio.uio_procp = cp; 1916 1917 if ((error = uvm_io(&vm->vm_map, &uio, 0)) != 0) 1918 goto out; 1919 1920 if (op == KERN_PROC_NARGV) { 1921 error = sysctl_rdint(oldp, oldlenp, NULL, pss.ps_nargvstr); 1922 goto out; 1923 } 1924 if (op == KERN_PROC_NENV) { 1925 error = sysctl_rdint(oldp, oldlenp, NULL, pss.ps_nenvstr); 1926 goto out; 1927 } 1928 1929 if (op == KERN_PROC_ARGV) { 1930 cnt = pss.ps_nargvstr; 1931 vargv = pss.ps_argvstr; 1932 } else { 1933 cnt = pss.ps_nenvstr; 1934 vargv = pss.ps_envstr; 1935 } 1936 1937 /* -1 to have space for a terminating NUL */ 1938 limit = *oldlenp - 1; 1939 *oldlenp = 0; 1940 1941 rargv = oldp; 1942 1943 /* 1944 * *oldlenp - number of bytes copied out into readers buffer. 1945 * limit - maximal number of bytes allowed into readers buffer. 1946 * rarg - pointer into readers buffer where next arg will be stored. 1947 * rargv - pointer into readers buffer where the next rarg pointer 1948 * will be stored. 1949 * vargv - pointer into victim address space where the next argument 1950 * will be read. 1951 */ 1952 1953 /* space for cnt pointers and a NULL */ 1954 rarg = (char *)(rargv + cnt + 1); 1955 *oldlenp += (cnt + 1) * sizeof(char **); 1956 1957 while (cnt > 0 && *oldlenp < limit) { 1958 size_t len, vstrlen; 1959 1960 /* Write to readers argv */ 1961 if ((error = copyout(&rarg, rargv, sizeof(rarg))) != 0) 1962 goto out; 1963 1964 /* read the victim argv */ 1965 iov.iov_base = &varg; 1966 iov.iov_len = sizeof(varg); 1967 uio.uio_iov = &iov; 1968 uio.uio_iovcnt = 1; 1969 uio.uio_offset = (off_t)(vaddr_t)vargv; 1970 uio.uio_resid = sizeof(varg); 1971 uio.uio_segflg = UIO_SYSSPACE; 1972 uio.uio_rw = UIO_READ; 1973 uio.uio_procp = cp; 1974 if ((error = uvm_io(&vm->vm_map, &uio, 0)) != 0) 1975 goto out; 1976 1977 if (varg == NULL) 1978 break; 1979 1980 /* 1981 * read the victim arg. We must jump through hoops to avoid 1982 * crossing a page boundary too much and returning an error. 1983 */ 1984 more: 1985 len = PAGE_SIZE - (((vaddr_t)varg) & PAGE_MASK); 1986 /* leave space for the terminating NUL */ 1987 iov.iov_base = buf; 1988 iov.iov_len = len; 1989 uio.uio_iov = &iov; 1990 uio.uio_iovcnt = 1; 1991 uio.uio_offset = (off_t)(vaddr_t)varg; 1992 uio.uio_resid = len; 1993 uio.uio_segflg = UIO_SYSSPACE; 1994 uio.uio_rw = UIO_READ; 1995 uio.uio_procp = cp; 1996 if ((error = uvm_io(&vm->vm_map, &uio, 0)) != 0) 1997 goto out; 1998 1999 for (vstrlen = 0; vstrlen < len; vstrlen++) { 2000 if (buf[vstrlen] == '\0') 2001 break; 2002 } 2003 2004 /* Don't overflow readers buffer. */ 2005 if (*oldlenp + vstrlen + 1 >= limit) { 2006 error = ENOMEM; 2007 goto out; 2008 } 2009 2010 if ((error = copyout(buf, rarg, vstrlen)) != 0) 2011 goto out; 2012 2013 *oldlenp += vstrlen; 2014 rarg += vstrlen; 2015 2016 /* The string didn't end in this page? */ 2017 if (vstrlen == len) { 2018 varg += vstrlen; 2019 goto more; 2020 } 2021 2022 /* End of string. Terminate it with a NUL */ 2023 buf[0] = '\0'; 2024 if ((error = copyout(buf, rarg, 1)) != 0) 2025 goto out; 2026 *oldlenp += 1; 2027 rarg += 1; 2028 2029 vargv++; 2030 rargv++; 2031 cnt--; 2032 } 2033 2034 if (*oldlenp >= limit) { 2035 error = ENOMEM; 2036 goto out; 2037 } 2038 2039 /* Write the terminating null */ 2040 rarg = NULL; 2041 error = copyout(&rarg, rargv, sizeof(rarg)); 2042 2043 out: 2044 uvmspace_free(vm); 2045 free(buf, M_TEMP, PAGE_SIZE); 2046 return (error); 2047 } 2048 2049 int 2050 sysctl_proc_cwd(int *name, u_int namelen, void *oldp, size_t *oldlenp, 2051 struct proc *cp) 2052 { 2053 struct process *findpr; 2054 struct vnode *vp; 2055 pid_t pid; 2056 int error; 2057 size_t lenused, len; 2058 char *path, *bp, *bend; 2059 2060 if (namelen > 1) 2061 return (ENOTDIR); 2062 if (namelen < 1) 2063 return (EINVAL); 2064 2065 pid = name[0]; 2066 if ((findpr = prfind(pid)) == NULL) 2067 return (ESRCH); 2068 2069 if (oldp == NULL) { 2070 *oldlenp = MAXPATHLEN * 4; 2071 return (0); 2072 } 2073 2074 /* Either system process or exiting/zombie */ 2075 if (findpr->ps_flags & (PS_SYSTEM | PS_EXITING)) 2076 return (EINVAL); 2077 2078 /* Only owner or root can get cwd */ 2079 if (findpr->ps_ucred->cr_uid != cp->p_ucred->cr_uid && 2080 (error = suser(cp)) != 0) 2081 return (error); 2082 2083 len = *oldlenp; 2084 if (len > MAXPATHLEN * 4) 2085 len = MAXPATHLEN * 4; 2086 else if (len < 2) 2087 return (ERANGE); 2088 *oldlenp = 0; 2089 2090 /* snag a reference to the vnode before we can sleep */ 2091 vp = findpr->ps_fd->fd_cdir; 2092 vref(vp); 2093 2094 path = malloc(len, M_TEMP, M_WAITOK); 2095 2096 bp = &path[len]; 2097 bend = bp; 2098 *(--bp) = '\0'; 2099 2100 /* Same as sys__getcwd */ 2101 error = vfs_getcwd_common(vp, NULL, 2102 &bp, path, len / 2, GETCWD_CHECK_ACCESS, cp); 2103 if (error == 0) { 2104 *oldlenp = lenused = bend - bp; 2105 error = copyout(bp, oldp, lenused); 2106 } 2107 2108 vrele(vp); 2109 free(path, M_TEMP, len); 2110 2111 return (error); 2112 } 2113 2114 int 2115 sysctl_proc_nobroadcastkill(int *name, u_int namelen, void *newp, size_t newlen, 2116 void *oldp, size_t *oldlenp, struct proc *cp) 2117 { 2118 struct process *findpr; 2119 pid_t pid; 2120 int error, flag; 2121 2122 if (namelen > 1) 2123 return (ENOTDIR); 2124 if (namelen < 1) 2125 return (EINVAL); 2126 2127 pid = name[0]; 2128 if ((findpr = prfind(pid)) == NULL) 2129 return (ESRCH); 2130 2131 /* Either system process or exiting/zombie */ 2132 if (findpr->ps_flags & (PS_SYSTEM | PS_EXITING)) 2133 return (EINVAL); 2134 2135 /* Only root can change PS_NOBROADCASTKILL */ 2136 if (newp != NULL && (error = suser(cp)) != 0) 2137 return (error); 2138 2139 /* get the PS_NOBROADCASTKILL flag */ 2140 flag = findpr->ps_flags & PS_NOBROADCASTKILL ? 1 : 0; 2141 2142 error = sysctl_int(oldp, oldlenp, newp, newlen, &flag); 2143 if (error == 0 && newp) { 2144 if (flag) 2145 atomic_setbits_int(&findpr->ps_flags, 2146 PS_NOBROADCASTKILL); 2147 else 2148 atomic_clearbits_int(&findpr->ps_flags, 2149 PS_NOBROADCASTKILL); 2150 } 2151 2152 return (error); 2153 } 2154 2155 /* Arbitrary but reasonable limit for one iteration. */ 2156 #define VMMAP_MAXLEN MAXPHYS 2157 2158 int 2159 sysctl_proc_vmmap(int *name, u_int namelen, void *oldp, size_t *oldlenp, 2160 struct proc *cp) 2161 { 2162 struct process *findpr; 2163 pid_t pid; 2164 int error; 2165 size_t oldlen, len; 2166 struct kinfo_vmentry *kve, *ukve; 2167 u_long *ustart, start; 2168 2169 if (namelen > 1) 2170 return (ENOTDIR); 2171 if (namelen < 1) 2172 return (EINVAL); 2173 2174 /* Provide max buffer length as hint. */ 2175 if (oldp == NULL) { 2176 if (oldlenp == NULL) 2177 return (EINVAL); 2178 else { 2179 *oldlenp = VMMAP_MAXLEN; 2180 return (0); 2181 } 2182 } 2183 2184 pid = name[0]; 2185 if (pid == cp->p_p->ps_pid) { 2186 /* Self process mapping. */ 2187 findpr = cp->p_p; 2188 } else if (pid > 0) { 2189 if ((findpr = prfind(pid)) == NULL) 2190 return (ESRCH); 2191 2192 /* Either system process or exiting/zombie */ 2193 if (findpr->ps_flags & (PS_SYSTEM | PS_EXITING)) 2194 return (EINVAL); 2195 2196 #if 1 2197 /* XXX Allow only root for now */ 2198 if ((error = suser(cp)) != 0) 2199 return (error); 2200 #else 2201 /* Only owner or root can get vmmap */ 2202 if (findpr->ps_ucred->cr_uid != cp->p_ucred->cr_uid && 2203 (error = suser(cp)) != 0) 2204 return (error); 2205 #endif 2206 } else { 2207 /* Only root can get kernel_map */ 2208 if ((error = suser(cp)) != 0) 2209 return (error); 2210 findpr = NULL; 2211 } 2212 2213 /* Check the given size. */ 2214 oldlen = *oldlenp; 2215 if (oldlen == 0 || oldlen % sizeof(*kve) != 0) 2216 return (EINVAL); 2217 2218 /* Deny huge allocation. */ 2219 if (oldlen > VMMAP_MAXLEN) 2220 return (EINVAL); 2221 2222 /* 2223 * Iterate from the given address passed as the first element's 2224 * kve_start via oldp. 2225 */ 2226 ukve = (struct kinfo_vmentry *)oldp; 2227 ustart = &ukve->kve_start; 2228 error = copyin(ustart, &start, sizeof(start)); 2229 if (error != 0) 2230 return (error); 2231 2232 /* Allocate wired memory to not block. */ 2233 kve = malloc(oldlen, M_TEMP, M_WAITOK); 2234 2235 /* Set the base address and read entries. */ 2236 kve[0].kve_start = start; 2237 len = oldlen; 2238 error = fill_vmmap(findpr, kve, &len); 2239 if (error != 0 && error != ENOMEM) 2240 goto done; 2241 if (len == 0) 2242 goto done; 2243 2244 KASSERT(len <= oldlen); 2245 KASSERT((len % sizeof(struct kinfo_vmentry)) == 0); 2246 2247 error = copyout(kve, oldp, len); 2248 2249 done: 2250 *oldlenp = len; 2251 2252 free(kve, M_TEMP, oldlen); 2253 2254 return (error); 2255 } 2256 #endif 2257 2258 /* 2259 * Initialize disknames/diskstats for export by sysctl. If update is set, 2260 * then we simply update the disk statistics information. 2261 */ 2262 int 2263 sysctl_diskinit(int update, struct proc *p) 2264 { 2265 struct diskstats *sdk; 2266 struct disk *dk; 2267 const char *duid; 2268 int error, changed = 0; 2269 2270 KERNEL_ASSERT_LOCKED(); 2271 2272 if ((error = rw_enter(&sysctl_disklock, RW_WRITE|RW_INTR)) != 0) 2273 return error; 2274 2275 /* Run in a loop, disks may change while malloc sleeps. */ 2276 while (disk_change) { 2277 int tlen; 2278 2279 disk_change = 0; 2280 2281 tlen = 0; 2282 TAILQ_FOREACH(dk, &disklist, dk_link) { 2283 if (dk->dk_name) 2284 tlen += strlen(dk->dk_name); 2285 tlen += 18; /* label uid + separators */ 2286 } 2287 tlen++; 2288 2289 /* 2290 * The sysctl_disklock ensures that no other process can 2291 * allocate disknames and diskstats while our malloc sleeps. 2292 */ 2293 free(disknames, M_SYSCTL, disknameslen); 2294 free(diskstats, M_SYSCTL, diskstatslen); 2295 diskstats = NULL; 2296 disknames = NULL; 2297 diskstats = mallocarray(disk_count, sizeof(struct diskstats), 2298 M_SYSCTL, M_WAITOK|M_ZERO); 2299 diskstatslen = disk_count * sizeof(struct diskstats); 2300 disknames = malloc(tlen, M_SYSCTL, M_WAITOK|M_ZERO); 2301 disknameslen = tlen; 2302 disknames[0] = '\0'; 2303 changed = 1; 2304 } 2305 2306 if (changed) { 2307 int l; 2308 2309 l = 0; 2310 sdk = diskstats; 2311 TAILQ_FOREACH(dk, &disklist, dk_link) { 2312 duid = NULL; 2313 if (dk->dk_label && !duid_iszero(dk->dk_label->d_uid)) 2314 duid = duid_format(dk->dk_label->d_uid); 2315 snprintf(disknames + l, disknameslen - l, "%s:%s,", 2316 dk->dk_name ? dk->dk_name : "", 2317 duid ? duid : ""); 2318 l += strlen(disknames + l); 2319 strlcpy(sdk->ds_name, dk->dk_name, 2320 sizeof(sdk->ds_name)); 2321 mtx_enter(&dk->dk_mtx); 2322 sdk->ds_busy = dk->dk_busy; 2323 sdk->ds_rxfer = dk->dk_rxfer; 2324 sdk->ds_wxfer = dk->dk_wxfer; 2325 sdk->ds_seek = dk->dk_seek; 2326 sdk->ds_rbytes = dk->dk_rbytes; 2327 sdk->ds_wbytes = dk->dk_wbytes; 2328 sdk->ds_attachtime = dk->dk_attachtime; 2329 sdk->ds_timestamp = dk->dk_timestamp; 2330 sdk->ds_time = dk->dk_time; 2331 mtx_leave(&dk->dk_mtx); 2332 sdk++; 2333 } 2334 2335 /* Eliminate trailing comma */ 2336 if (l != 0) 2337 disknames[l - 1] = '\0'; 2338 } else if (update) { 2339 /* Just update, number of drives hasn't changed */ 2340 sdk = diskstats; 2341 TAILQ_FOREACH(dk, &disklist, dk_link) { 2342 strlcpy(sdk->ds_name, dk->dk_name, 2343 sizeof(sdk->ds_name)); 2344 mtx_enter(&dk->dk_mtx); 2345 sdk->ds_busy = dk->dk_busy; 2346 sdk->ds_rxfer = dk->dk_rxfer; 2347 sdk->ds_wxfer = dk->dk_wxfer; 2348 sdk->ds_seek = dk->dk_seek; 2349 sdk->ds_rbytes = dk->dk_rbytes; 2350 sdk->ds_wbytes = dk->dk_wbytes; 2351 sdk->ds_attachtime = dk->dk_attachtime; 2352 sdk->ds_timestamp = dk->dk_timestamp; 2353 sdk->ds_time = dk->dk_time; 2354 mtx_leave(&dk->dk_mtx); 2355 sdk++; 2356 } 2357 } 2358 rw_exit_write(&sysctl_disklock); 2359 return 0; 2360 } 2361 2362 #if defined(SYSVMSG) || defined(SYSVSEM) || defined(SYSVSHM) 2363 int 2364 sysctl_sysvipc(int *name, u_int namelen, void *where, size_t *sizep) 2365 { 2366 #ifdef SYSVSEM 2367 struct sem_sysctl_info *semsi; 2368 #endif 2369 #ifdef SYSVSHM 2370 struct shm_sysctl_info *shmsi; 2371 #endif 2372 size_t infosize, dssize, tsize, buflen, bufsiz; 2373 int i, nds, error, ret; 2374 void *buf; 2375 2376 if (namelen != 1) 2377 return (EINVAL); 2378 2379 buflen = *sizep; 2380 2381 switch (*name) { 2382 case KERN_SYSVIPC_MSG_INFO: 2383 #ifdef SYSVMSG 2384 return (sysctl_sysvmsg(name, namelen, where, sizep)); 2385 #else 2386 return (EOPNOTSUPP); 2387 #endif 2388 case KERN_SYSVIPC_SEM_INFO: 2389 #ifdef SYSVSEM 2390 infosize = sizeof(semsi->seminfo); 2391 nds = seminfo.semmni; 2392 dssize = sizeof(semsi->semids[0]); 2393 break; 2394 #else 2395 return (EOPNOTSUPP); 2396 #endif 2397 case KERN_SYSVIPC_SHM_INFO: 2398 #ifdef SYSVSHM 2399 infosize = sizeof(shmsi->shminfo); 2400 nds = shminfo.shmmni; 2401 dssize = sizeof(shmsi->shmids[0]); 2402 break; 2403 #else 2404 return (EOPNOTSUPP); 2405 #endif 2406 default: 2407 return (EINVAL); 2408 } 2409 tsize = infosize + (nds * dssize); 2410 2411 /* Return just the total size required. */ 2412 if (where == NULL) { 2413 *sizep = tsize; 2414 return (0); 2415 } 2416 2417 /* Not enough room for even the info struct. */ 2418 if (buflen < infosize) { 2419 *sizep = 0; 2420 return (ENOMEM); 2421 } 2422 bufsiz = min(tsize, buflen); 2423 buf = malloc(bufsiz, M_TEMP, M_WAITOK|M_ZERO); 2424 2425 switch (*name) { 2426 #ifdef SYSVSEM 2427 case KERN_SYSVIPC_SEM_INFO: 2428 semsi = (struct sem_sysctl_info *)buf; 2429 semsi->seminfo = seminfo; 2430 break; 2431 #endif 2432 #ifdef SYSVSHM 2433 case KERN_SYSVIPC_SHM_INFO: 2434 shmsi = (struct shm_sysctl_info *)buf; 2435 shmsi->shminfo = shminfo; 2436 break; 2437 #endif 2438 } 2439 buflen -= infosize; 2440 2441 ret = 0; 2442 if (buflen > 0) { 2443 /* Fill in the IPC data structures. */ 2444 for (i = 0; i < nds; i++) { 2445 if (buflen < dssize) { 2446 ret = ENOMEM; 2447 break; 2448 } 2449 switch (*name) { 2450 #ifdef SYSVSEM 2451 case KERN_SYSVIPC_SEM_INFO: 2452 if (sema[i] != NULL) 2453 memcpy(&semsi->semids[i], sema[i], 2454 dssize); 2455 else 2456 memset(&semsi->semids[i], 0, dssize); 2457 break; 2458 #endif 2459 #ifdef SYSVSHM 2460 case KERN_SYSVIPC_SHM_INFO: 2461 if (shmsegs[i] != NULL) 2462 memcpy(&shmsi->shmids[i], shmsegs[i], 2463 dssize); 2464 else 2465 memset(&shmsi->shmids[i], 0, dssize); 2466 break; 2467 #endif 2468 } 2469 buflen -= dssize; 2470 } 2471 } 2472 *sizep -= buflen; 2473 error = copyout(buf, where, *sizep); 2474 free(buf, M_TEMP, bufsiz); 2475 /* If copyout succeeded, use return code set earlier. */ 2476 return (error ? error : ret); 2477 } 2478 #endif /* SYSVMSG || SYSVSEM || SYSVSHM */ 2479 2480 #ifndef SMALL_KERNEL 2481 2482 int 2483 sysctl_intrcnt(int *name, u_int namelen, void *oldp, size_t *oldlenp) 2484 { 2485 return (evcount_sysctl(name, namelen, oldp, oldlenp, NULL, 0)); 2486 } 2487 2488 2489 int 2490 sysctl_sensors(int *name, u_int namelen, void *oldp, size_t *oldlenp, 2491 void *newp, size_t newlen) 2492 { 2493 struct ksensor *ks; 2494 struct sensor *us; 2495 struct ksensordev *ksd; 2496 struct sensordev *usd; 2497 int dev, numt, ret; 2498 enum sensor_type type; 2499 2500 if (namelen != 1 && namelen != 3) 2501 return (ENOTDIR); 2502 2503 dev = name[0]; 2504 if (namelen == 1) { 2505 ret = sensordev_get(dev, &ksd); 2506 if (ret) 2507 return (ret); 2508 2509 /* Grab a copy, to clear the kernel pointers */ 2510 usd = malloc(sizeof(*usd), M_TEMP, M_WAITOK|M_ZERO); 2511 usd->num = ksd->num; 2512 strlcpy(usd->xname, ksd->xname, sizeof(usd->xname)); 2513 memcpy(usd->maxnumt, ksd->maxnumt, sizeof(usd->maxnumt)); 2514 usd->sensors_count = ksd->sensors_count; 2515 2516 ret = sysctl_rdstruct(oldp, oldlenp, newp, usd, 2517 sizeof(struct sensordev)); 2518 2519 free(usd, M_TEMP, sizeof(*usd)); 2520 return (ret); 2521 } 2522 2523 type = name[1]; 2524 numt = name[2]; 2525 2526 ret = sensor_find(dev, type, numt, &ks); 2527 if (ret) 2528 return (ret); 2529 2530 /* Grab a copy, to clear the kernel pointers */ 2531 us = malloc(sizeof(*us), M_TEMP, M_WAITOK|M_ZERO); 2532 memcpy(us->desc, ks->desc, sizeof(us->desc)); 2533 us->tv = ks->tv; 2534 us->value = ks->value; 2535 us->type = ks->type; 2536 us->status = ks->status; 2537 us->numt = ks->numt; 2538 us->flags = ks->flags; 2539 2540 ret = sysctl_rdstruct(oldp, oldlenp, newp, us, 2541 sizeof(struct sensor)); 2542 free(us, M_TEMP, sizeof(*us)); 2543 return (ret); 2544 } 2545 #endif /* SMALL_KERNEL */ 2546 2547 int 2548 sysctl_cptime2(int *name, u_int namelen, void *oldp, size_t *oldlenp, 2549 void *newp, size_t newlen) 2550 { 2551 CPU_INFO_ITERATOR cii; 2552 struct cpu_info *ci; 2553 int found = 0; 2554 2555 if (namelen != 1) 2556 return (ENOTDIR); 2557 2558 CPU_INFO_FOREACH(cii, ci) { 2559 if (name[0] == CPU_INFO_UNIT(ci)) { 2560 found = 1; 2561 break; 2562 } 2563 } 2564 if (!found) 2565 return (ENOENT); 2566 2567 return (sysctl_rdstruct(oldp, oldlenp, newp, 2568 &ci->ci_schedstate.spc_cp_time, 2569 sizeof(ci->ci_schedstate.spc_cp_time))); 2570 } 2571 2572 #if NAUDIO > 0 2573 int 2574 sysctl_audio(int *name, u_int namelen, void *oldp, size_t *oldlenp, 2575 void *newp, size_t newlen) 2576 { 2577 if (namelen != 1) 2578 return (ENOTDIR); 2579 2580 if (name[0] != KERN_AUDIO_RECORD) 2581 return (ENOENT); 2582 2583 return (sysctl_int(oldp, oldlenp, newp, newlen, &audio_record_enable)); 2584 } 2585 #endif 2586 2587 #if NVIDEO > 0 2588 int 2589 sysctl_video(int *name, u_int namelen, void *oldp, size_t *oldlenp, 2590 void *newp, size_t newlen) 2591 { 2592 if (namelen != 1) 2593 return (ENOTDIR); 2594 2595 if (name[0] != KERN_VIDEO_RECORD) 2596 return (ENOENT); 2597 2598 return (sysctl_int(oldp, oldlenp, newp, newlen, &video_record_enable)); 2599 } 2600 #endif 2601 2602 int 2603 sysctl_cpustats(int *name, u_int namelen, void *oldp, size_t *oldlenp, 2604 void *newp, size_t newlen) 2605 { 2606 CPU_INFO_ITERATOR cii; 2607 struct cpustats cs; 2608 struct cpu_info *ci; 2609 int found = 0; 2610 2611 if (namelen != 1) 2612 return (ENOTDIR); 2613 2614 CPU_INFO_FOREACH(cii, ci) { 2615 if (name[0] == CPU_INFO_UNIT(ci)) { 2616 found = 1; 2617 break; 2618 } 2619 } 2620 if (!found) 2621 return (ENOENT); 2622 2623 memset(&cs, 0, sizeof cs); 2624 memcpy(&cs.cs_time, &ci->ci_schedstate.spc_cp_time, sizeof(cs.cs_time)); 2625 cs.cs_flags = 0; 2626 if (cpu_is_online(ci)) 2627 cs.cs_flags |= CPUSTATS_ONLINE; 2628 2629 return (sysctl_rdstruct(oldp, oldlenp, newp, &cs, sizeof(cs))); 2630 } 2631 2632 int 2633 sysctl_utc_offset(void *oldp, size_t *oldlenp, void *newp, size_t newlen) 2634 { 2635 struct timespec adjusted, now; 2636 int adjustment_seconds, error, new_offset_minutes, old_offset_minutes; 2637 2638 old_offset_minutes = utc_offset / 60; /* seconds -> minutes */ 2639 new_offset_minutes = old_offset_minutes; 2640 error = sysctl_securelevel_int(oldp, oldlenp, newp, newlen, 2641 &new_offset_minutes); 2642 if (error) 2643 return error; 2644 if (new_offset_minutes < -24 * 60 || new_offset_minutes > 24 * 60) 2645 return EINVAL; 2646 if (new_offset_minutes == old_offset_minutes) 2647 return 0; 2648 2649 utc_offset = new_offset_minutes * 60; /* minutes -> seconds */ 2650 adjustment_seconds = (new_offset_minutes - old_offset_minutes) * 60; 2651 2652 nanotime(&now); 2653 adjusted = now; 2654 adjusted.tv_sec -= adjustment_seconds; 2655 tc_setrealtimeclock(&adjusted); 2656 resettodr(); 2657 2658 return 0; 2659 } 2660