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