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