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