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