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