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