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