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