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