1 /* $NetBSD: kern_sysctl.c,v 1.101 2002/01/31 00:32:47 kleink Exp $ */ 2 3 /*- 4 * Copyright (c) 1982, 1986, 1989, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * Mike Karels at Berkeley Software Design, Inc. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the University of 21 * California, Berkeley and its contributors. 22 * 4. Neither the name of the University nor the names of its contributors 23 * may be used to endorse or promote products derived from this software 24 * without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 * 38 * @(#)kern_sysctl.c 8.9 (Berkeley) 5/20/95 39 */ 40 41 /* 42 * sysctl system call. 43 */ 44 45 #include <sys/cdefs.h> 46 __KERNEL_RCSID(0, "$NetBSD: kern_sysctl.c,v 1.101 2002/01/31 00:32:47 kleink Exp $"); 47 48 #include "opt_ddb.h" 49 #include "opt_insecure.h" 50 #include "opt_defcorename.h" 51 #include "opt_new_pipe.h" 52 #include "opt_sysv.h" 53 #include "pty.h" 54 55 #include <sys/param.h> 56 #include <sys/systm.h> 57 #include <sys/kernel.h> 58 #include <sys/buf.h> 59 #include <sys/device.h> 60 #include <sys/disklabel.h> 61 #include <sys/dkstat.h> 62 #include <sys/exec.h> 63 #include <sys/file.h> 64 #include <sys/ioctl.h> 65 #include <sys/malloc.h> 66 #include <sys/mount.h> 67 #include <sys/msgbuf.h> 68 #include <sys/pool.h> 69 #include <sys/proc.h> 70 #include <sys/resource.h> 71 #include <sys/resourcevar.h> 72 #include <sys/syscallargs.h> 73 #include <sys/tty.h> 74 #include <sys/unistd.h> 75 #include <sys/vnode.h> 76 #include <sys/socketvar.h> 77 #define __SYSCTL_PRIVATE 78 #include <sys/sysctl.h> 79 #include <sys/lock.h> 80 #include <sys/namei.h> 81 82 #if defined(SYSVMSG) || defined(SYSVSEM) || defined(SYSVSHM) 83 #include <sys/ipc.h> 84 #endif 85 #ifdef SYSVMSG 86 #include <sys/msg.h> 87 #endif 88 #ifdef SYSVSEM 89 #include <sys/sem.h> 90 #endif 91 #ifdef SYSVSHM 92 #include <sys/shm.h> 93 #endif 94 95 #include <dev/cons.h> 96 97 #if defined(DDB) 98 #include <ddb/ddbvar.h> 99 #endif 100 101 #ifdef NEW_PIPE 102 #include <sys/pipe.h> 103 #endif 104 105 #define PTRTOINT64(foo) ((u_int64_t)(uintptr_t)(foo)) 106 107 static int sysctl_file(void *, size_t *); 108 #if defined(SYSVMSG) || defined(SYSVSEM) || defined(SYSVSHM) 109 static int sysctl_sysvipc(int *, u_int, void *, size_t *); 110 #endif 111 static int sysctl_msgbuf(void *, size_t *); 112 static int sysctl_doeproc(int *, u_int, void *, size_t *); 113 static int sysctl_dotkstat(int *, u_int, void *, size_t *, void *); 114 #ifdef MULTIPROCESSOR 115 static int sysctl_docptime(void *, size_t *, void *); 116 static int sysctl_ncpus(void); 117 #endif 118 static void fill_kproc2(struct proc *, struct kinfo_proc2 *); 119 static int sysctl_procargs(int *, u_int, void *, size_t *, struct proc *); 120 #if NPTY > 0 121 static int sysctl_pty(void *, size_t *, void *, size_t); 122 #endif 123 124 /* 125 * The `sysctl_memlock' is intended to keep too many processes from 126 * locking down memory by doing sysctls at once. Whether or not this 127 * is really a good idea to worry about it probably a subject of some 128 * debate. 129 */ 130 struct lock sysctl_memlock; 131 132 void 133 sysctl_init(void) 134 { 135 136 lockinit(&sysctl_memlock, PRIBIO|PCATCH, "sysctl", 0, 0); 137 } 138 139 int 140 sys___sysctl(struct proc *p, void *v, register_t *retval) 141 { 142 struct sys___sysctl_args /* { 143 syscallarg(int *) name; 144 syscallarg(u_int) namelen; 145 syscallarg(void *) old; 146 syscallarg(size_t *) oldlenp; 147 syscallarg(void *) new; 148 syscallarg(size_t) newlen; 149 } */ *uap = v; 150 int error; 151 size_t savelen = 0, oldlen = 0; 152 sysctlfn *fn; 153 int name[CTL_MAXNAME]; 154 size_t *oldlenp; 155 156 /* 157 * all top-level sysctl names are non-terminal 158 */ 159 if (SCARG(uap, namelen) > CTL_MAXNAME || SCARG(uap, namelen) < 2) 160 return (EINVAL); 161 error = copyin(SCARG(uap, name), &name, 162 SCARG(uap, namelen) * sizeof(int)); 163 if (error) 164 return (error); 165 166 /* 167 * For all but CTL_PROC, must be root to change a value. 168 * For CTL_PROC, must be root, or owner of the proc (and not suid), 169 * this is checked in proc_sysctl() (once we know the targer proc). 170 */ 171 if (SCARG(uap, new) != NULL && name[0] != CTL_PROC && 172 (error = suser(p->p_ucred, &p->p_acflag))) 173 return error; 174 175 switch (name[0]) { 176 case CTL_KERN: 177 fn = kern_sysctl; 178 break; 179 case CTL_HW: 180 fn = hw_sysctl; 181 break; 182 case CTL_VM: 183 fn = uvm_sysctl; 184 break; 185 case CTL_NET: 186 fn = net_sysctl; 187 break; 188 case CTL_VFS: 189 fn = vfs_sysctl; 190 break; 191 case CTL_MACHDEP: 192 fn = cpu_sysctl; 193 break; 194 #ifdef DEBUG 195 case CTL_DEBUG: 196 fn = debug_sysctl; 197 break; 198 #endif 199 #ifdef DDB 200 case CTL_DDB: 201 fn = ddb_sysctl; 202 break; 203 #endif 204 case CTL_PROC: 205 fn = proc_sysctl; 206 break; 207 default: 208 return (EOPNOTSUPP); 209 } 210 211 /* 212 * XXX Hey, we wire `old', but what about `new'? 213 */ 214 215 oldlenp = SCARG(uap, oldlenp); 216 if (oldlenp) { 217 if ((error = copyin(oldlenp, &oldlen, sizeof(oldlen)))) 218 return (error); 219 oldlenp = &oldlen; 220 } 221 if (SCARG(uap, old) != NULL) { 222 error = lockmgr(&sysctl_memlock, LK_EXCLUSIVE, NULL); 223 if (error) 224 return (error); 225 error = uvm_vslock(p, SCARG(uap, old), oldlen, 226 VM_PROT_READ|VM_PROT_WRITE); 227 if (error) { 228 (void) lockmgr(&sysctl_memlock, LK_RELEASE, NULL); 229 return error; 230 } 231 savelen = oldlen; 232 } 233 error = (*fn)(name + 1, SCARG(uap, namelen) - 1, SCARG(uap, old), 234 oldlenp, SCARG(uap, new), SCARG(uap, newlen), p); 235 if (SCARG(uap, old) != NULL) { 236 uvm_vsunlock(p, SCARG(uap, old), savelen); 237 (void) lockmgr(&sysctl_memlock, LK_RELEASE, NULL); 238 } 239 if (error) 240 return (error); 241 if (SCARG(uap, oldlenp)) 242 error = copyout(&oldlen, SCARG(uap, oldlenp), sizeof(oldlen)); 243 return (error); 244 } 245 246 /* 247 * Attributes stored in the kernel. 248 */ 249 char hostname[MAXHOSTNAMELEN]; 250 int hostnamelen; 251 252 char domainname[MAXHOSTNAMELEN]; 253 int domainnamelen; 254 255 long hostid; 256 257 #ifdef INSECURE 258 int securelevel = -1; 259 #else 260 int securelevel = 0; 261 #endif 262 263 #ifndef DEFCORENAME 264 #define DEFCORENAME "%n.core" 265 #endif 266 char defcorename[MAXPATHLEN] = DEFCORENAME; 267 int defcorenamelen = sizeof(DEFCORENAME); 268 269 extern int kern_logsigexit; 270 extern fixpt_t ccpu; 271 272 #ifndef MULTIPROCESSOR 273 #define sysctl_ncpus() 1 274 #endif 275 276 #ifdef MULTIPROCESSOR 277 278 #ifndef CPU_INFO_FOREACH 279 #define CPU_INFO_ITERATOR int 280 #define CPU_INFO_FOREACH(cii, ci) cii = 0, ci = curcpu(); ci != NULL; ci = NULL 281 #endif 282 283 static int 284 sysctl_docptime(void *oldp, size_t *oldlenp, void *newp) 285 { 286 u_int64_t cp_time[CPUSTATES]; 287 int i; 288 struct cpu_info *ci; 289 CPU_INFO_ITERATOR cii; 290 291 for (i=0; i<CPUSTATES; i++) 292 cp_time[i] = 0; 293 294 for (CPU_INFO_FOREACH(cii, ci)) { 295 for (i=0; i<CPUSTATES; i++) 296 cp_time[i] += ci->ci_schedstate.spc_cp_time[i]; 297 } 298 return (sysctl_rdstruct(oldp, oldlenp, newp, 299 cp_time, sizeof(cp_time))); 300 } 301 302 static int 303 sysctl_ncpus(void) 304 { 305 struct cpu_info *ci; 306 CPU_INFO_ITERATOR cii; 307 308 int ncpus = 0; 309 for (CPU_INFO_FOREACH(cii, ci)) 310 ncpus++; 311 return ncpus; 312 } 313 314 #endif 315 316 /* 317 * kernel related system variables. 318 */ 319 int 320 kern_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, 321 void *newp, size_t newlen, struct proc *p) 322 { 323 int error, level, inthostid; 324 int old_autonicetime; 325 int old_vnodes; 326 dev_t consdev; 327 328 /* All sysctl names at this level, except for a few, are terminal. */ 329 switch (name[0]) { 330 case KERN_PROC: 331 case KERN_PROC2: 332 case KERN_PROF: 333 case KERN_MBUF: 334 case KERN_PROC_ARGS: 335 case KERN_SYSVIPC_INFO: 336 case KERN_PIPE: 337 case KERN_TKSTAT: 338 /* Not terminal. */ 339 break; 340 default: 341 if (namelen != 1) 342 return (ENOTDIR); /* overloaded */ 343 } 344 345 switch (name[0]) { 346 case KERN_OSTYPE: 347 return (sysctl_rdstring(oldp, oldlenp, newp, ostype)); 348 case KERN_OSRELEASE: 349 return (sysctl_rdstring(oldp, oldlenp, newp, osrelease)); 350 case KERN_OSREV: 351 return (sysctl_rdint(oldp, oldlenp, newp, __NetBSD_Version__)); 352 case KERN_VERSION: 353 return (sysctl_rdstring(oldp, oldlenp, newp, version)); 354 case KERN_MAXVNODES: 355 old_vnodes = desiredvnodes; 356 error = sysctl_int(oldp, oldlenp, newp, newlen, &desiredvnodes); 357 if (newp && !error) { 358 if (old_vnodes > desiredvnodes) { 359 desiredvnodes = old_vnodes; 360 return (EINVAL); 361 } 362 vfs_reinit(); 363 nchreinit(); 364 } 365 return (error); 366 case KERN_MAXPROC: 367 return (sysctl_int(oldp, oldlenp, newp, newlen, &maxproc)); 368 case KERN_MAXFILES: 369 return (sysctl_int(oldp, oldlenp, newp, newlen, &maxfiles)); 370 case KERN_ARGMAX: 371 return (sysctl_rdint(oldp, oldlenp, newp, ARG_MAX)); 372 case KERN_SECURELVL: 373 level = securelevel; 374 if ((error = sysctl_int(oldp, oldlenp, newp, newlen, &level)) || 375 newp == NULL) 376 return (error); 377 if (level < securelevel && p->p_pid != 1) 378 return (EPERM); 379 securelevel = level; 380 return (0); 381 case KERN_HOSTNAME: 382 error = sysctl_string(oldp, oldlenp, newp, newlen, 383 hostname, sizeof(hostname)); 384 if (newp && !error) 385 hostnamelen = newlen; 386 return (error); 387 case KERN_DOMAINNAME: 388 error = sysctl_string(oldp, oldlenp, newp, newlen, 389 domainname, sizeof(domainname)); 390 if (newp && !error) 391 domainnamelen = newlen; 392 return (error); 393 case KERN_HOSTID: 394 inthostid = hostid; /* XXX assumes sizeof long <= sizeof int */ 395 error = sysctl_int(oldp, oldlenp, newp, newlen, &inthostid); 396 if (newp && !error) 397 hostid = inthostid; 398 return (error); 399 case KERN_CLOCKRATE: 400 return (sysctl_clockrate(oldp, oldlenp)); 401 case KERN_BOOTTIME: 402 return (sysctl_rdstruct(oldp, oldlenp, newp, &boottime, 403 sizeof(struct timeval))); 404 case KERN_VNODE: 405 return (sysctl_vnode(oldp, oldlenp, p)); 406 case KERN_PROC: 407 case KERN_PROC2: 408 return (sysctl_doeproc(name, namelen, oldp, oldlenp)); 409 case KERN_PROC_ARGS: 410 return (sysctl_procargs(name + 1, namelen - 1, 411 oldp, oldlenp, p)); 412 case KERN_FILE: 413 return (sysctl_file(oldp, oldlenp)); 414 #ifdef GPROF 415 case KERN_PROF: 416 return (sysctl_doprof(name + 1, namelen - 1, oldp, oldlenp, 417 newp, newlen)); 418 #endif 419 case KERN_POSIX1: 420 return (sysctl_rdint(oldp, oldlenp, newp, _POSIX_VERSION)); 421 case KERN_NGROUPS: 422 return (sysctl_rdint(oldp, oldlenp, newp, NGROUPS_MAX)); 423 case KERN_JOB_CONTROL: 424 return (sysctl_rdint(oldp, oldlenp, newp, 1)); 425 case KERN_SAVED_IDS: 426 #ifdef _POSIX_SAVED_IDS 427 return (sysctl_rdint(oldp, oldlenp, newp, 1)); 428 #else 429 return (sysctl_rdint(oldp, oldlenp, newp, 0)); 430 #endif 431 case KERN_MAXPARTITIONS: 432 return (sysctl_rdint(oldp, oldlenp, newp, MAXPARTITIONS)); 433 case KERN_RAWPARTITION: 434 return (sysctl_rdint(oldp, oldlenp, newp, RAW_PART)); 435 #ifdef NTP 436 case KERN_NTPTIME: 437 return (sysctl_ntptime(oldp, oldlenp)); 438 #endif 439 case KERN_AUTONICETIME: 440 old_autonicetime = autonicetime; 441 error = sysctl_int(oldp, oldlenp, newp, newlen, &autonicetime); 442 if (autonicetime < 0) 443 autonicetime = old_autonicetime; 444 return (error); 445 case KERN_AUTONICEVAL: 446 error = sysctl_int(oldp, oldlenp, newp, newlen, &autoniceval); 447 if (autoniceval < PRIO_MIN) 448 autoniceval = PRIO_MIN; 449 if (autoniceval > PRIO_MAX) 450 autoniceval = PRIO_MAX; 451 return (error); 452 case KERN_RTC_OFFSET: 453 return (sysctl_rdint(oldp, oldlenp, newp, rtc_offset)); 454 case KERN_ROOT_DEVICE: 455 return (sysctl_rdstring(oldp, oldlenp, newp, 456 root_device->dv_xname)); 457 case KERN_MSGBUFSIZE: 458 /* 459 * deal with cases where the message buffer has 460 * become corrupted. 461 */ 462 if (!msgbufenabled || msgbufp->msg_magic != MSG_MAGIC) { 463 msgbufenabled = 0; 464 return (ENXIO); 465 } 466 return (sysctl_rdint(oldp, oldlenp, newp, msgbufp->msg_bufs)); 467 case KERN_FSYNC: 468 return (sysctl_rdint(oldp, oldlenp, newp, 1)); 469 case KERN_SYSVMSG: 470 #ifdef SYSVMSG 471 return (sysctl_rdint(oldp, oldlenp, newp, 1)); 472 #else 473 return (sysctl_rdint(oldp, oldlenp, newp, 0)); 474 #endif 475 case KERN_SYSVSEM: 476 #ifdef SYSVSEM 477 return (sysctl_rdint(oldp, oldlenp, newp, 1)); 478 #else 479 return (sysctl_rdint(oldp, oldlenp, newp, 0)); 480 #endif 481 case KERN_SYSVSHM: 482 #ifdef SYSVSHM 483 return (sysctl_rdint(oldp, oldlenp, newp, 1)); 484 #else 485 return (sysctl_rdint(oldp, oldlenp, newp, 0)); 486 #endif 487 case KERN_DEFCORENAME: 488 if (newp && newlen < 1) 489 return (EINVAL); 490 error = sysctl_string(oldp, oldlenp, newp, newlen, 491 defcorename, sizeof(defcorename)); 492 if (newp && !error) 493 defcorenamelen = newlen; 494 return (error); 495 case KERN_SYNCHRONIZED_IO: 496 return (sysctl_rdint(oldp, oldlenp, newp, 1)); 497 case KERN_IOV_MAX: 498 return (sysctl_rdint(oldp, oldlenp, newp, IOV_MAX)); 499 case KERN_MBUF: 500 return (sysctl_dombuf(name + 1, namelen - 1, oldp, oldlenp, 501 newp, newlen)); 502 case KERN_MAPPED_FILES: 503 return (sysctl_rdint(oldp, oldlenp, newp, 1)); 504 case KERN_MEMLOCK: 505 return (sysctl_rdint(oldp, oldlenp, newp, 1)); 506 case KERN_MEMLOCK_RANGE: 507 return (sysctl_rdint(oldp, oldlenp, newp, 1)); 508 case KERN_MEMORY_PROTECTION: 509 return (sysctl_rdint(oldp, oldlenp, newp, 1)); 510 case KERN_LOGIN_NAME_MAX: 511 return (sysctl_rdint(oldp, oldlenp, newp, LOGIN_NAME_MAX)); 512 case KERN_LOGSIGEXIT: 513 return (sysctl_int(oldp, oldlenp, newp, newlen, 514 &kern_logsigexit)); 515 case KERN_FSCALE: 516 return (sysctl_rdint(oldp, oldlenp, newp, FSCALE)); 517 case KERN_CCPU: 518 return (sysctl_rdint(oldp, oldlenp, newp, ccpu)); 519 case KERN_CP_TIME: 520 #ifndef MULTIPROCESSOR 521 return (sysctl_rdstruct(oldp, oldlenp, newp, 522 curcpu()->ci_schedstate.spc_cp_time, 523 sizeof(curcpu()->ci_schedstate.spc_cp_time))); 524 #else 525 return (sysctl_docptime(oldp, oldlenp, newp)); 526 #endif 527 #if defined(SYSVMSG) || defined(SYSVSEM) || defined(SYSVSHM) 528 case KERN_SYSVIPC_INFO: 529 return (sysctl_sysvipc(name + 1, namelen - 1, oldp, oldlenp)); 530 #endif 531 case KERN_MSGBUF: 532 return (sysctl_msgbuf(oldp, oldlenp)); 533 case KERN_CONSDEV: 534 if (cn_tab != NULL) 535 consdev = cn_tab->cn_dev; 536 else 537 consdev = NODEV; 538 return (sysctl_rdstruct(oldp, oldlenp, newp, &consdev, 539 sizeof consdev)); 540 #if NPTY > 0 541 case KERN_MAXPTYS: 542 return sysctl_pty(oldp, oldlenp, newp, newlen); 543 #endif 544 #ifdef NEW_PIPE 545 case KERN_PIPE: 546 return (sysctl_dopipe(name + 1, namelen - 1, oldp, oldlenp, 547 newp, newlen)); 548 #endif 549 case KERN_MAXPHYS: 550 return (sysctl_rdint(oldp, oldlenp, newp, MAXPHYS)); 551 case KERN_SBMAX: 552 { 553 int new_sbmax = sb_max; 554 555 error = sysctl_int(oldp, oldlenp, newp, newlen, &new_sbmax); 556 if (newp && !error) { 557 if (new_sbmax < (16 * 1024)) /* sanity */ 558 return (EINVAL); 559 sb_max = new_sbmax; 560 } 561 return (error); 562 } 563 case KERN_TKSTAT: 564 return (sysctl_dotkstat(name + 1, namelen - 1, oldp, oldlenp, 565 newp)); 566 case KERN_MONOTONIC_CLOCK: /* XXX _POSIX_VERSION */ 567 return (sysctl_rdint(oldp, oldlenp, newp, 200112)); 568 default: 569 return (EOPNOTSUPP); 570 } 571 /* NOTREACHED */ 572 } 573 574 /* 575 * hardware related system variables. 576 */ 577 int 578 hw_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, 579 void *newp, size_t newlen, struct proc *p) 580 { 581 582 /* All sysctl names at this level, except for a few, are terminal. */ 583 switch (name[0]) { 584 case HW_DISKSTATS: 585 /* Not terminal. */ 586 break; 587 default: 588 if (namelen != 1) 589 return (ENOTDIR); /* overloaded */ 590 } 591 592 switch (name[0]) { 593 case HW_MACHINE: 594 return (sysctl_rdstring(oldp, oldlenp, newp, machine)); 595 case HW_MACHINE_ARCH: 596 return (sysctl_rdstring(oldp, oldlenp, newp, machine_arch)); 597 case HW_MODEL: 598 return (sysctl_rdstring(oldp, oldlenp, newp, cpu_model)); 599 case HW_NCPU: 600 return (sysctl_rdint(oldp, oldlenp, newp, sysctl_ncpus())); 601 case HW_BYTEORDER: 602 return (sysctl_rdint(oldp, oldlenp, newp, BYTE_ORDER)); 603 case HW_PHYSMEM: 604 return (sysctl_rdint(oldp, oldlenp, newp, ctob(physmem))); 605 case HW_USERMEM: 606 return (sysctl_rdint(oldp, oldlenp, newp, 607 ctob(physmem - uvmexp.wired))); 608 case HW_PAGESIZE: 609 return (sysctl_rdint(oldp, oldlenp, newp, PAGE_SIZE)); 610 case HW_ALIGNBYTES: 611 return (sysctl_rdint(oldp, oldlenp, newp, ALIGNBYTES)); 612 case HW_DISKNAMES: 613 return (sysctl_disknames(oldp, oldlenp)); 614 case HW_DISKSTATS: 615 return (sysctl_diskstats(name + 1, namelen - 1, oldp, oldlenp)); 616 case HW_CNMAGIC: { 617 char magic[CNS_LEN]; 618 int error; 619 620 if (oldp) 621 cn_get_magic(magic, CNS_LEN); 622 error = sysctl_string(oldp, oldlenp, newp, newlen, 623 magic, sizeof(magic)); 624 if (newp && !error) { 625 error = cn_set_magic(magic); 626 } 627 return (error); 628 } 629 default: 630 return (EOPNOTSUPP); 631 } 632 /* NOTREACHED */ 633 } 634 635 #ifdef DEBUG 636 /* 637 * Debugging related system variables. 638 */ 639 struct ctldebug debug0, debug1, debug2, debug3, debug4; 640 struct ctldebug debug5, debug6, debug7, debug8, debug9; 641 struct ctldebug debug10, debug11, debug12, debug13, debug14; 642 struct ctldebug debug15, debug16, debug17, debug18, debug19; 643 static struct ctldebug *debugvars[CTL_DEBUG_MAXID] = { 644 &debug0, &debug1, &debug2, &debug3, &debug4, 645 &debug5, &debug6, &debug7, &debug8, &debug9, 646 &debug10, &debug11, &debug12, &debug13, &debug14, 647 &debug15, &debug16, &debug17, &debug18, &debug19, 648 }; 649 650 int 651 debug_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, 652 void *newp, size_t newlen, struct proc *p) 653 { 654 struct ctldebug *cdp; 655 656 /* all sysctl names at this level are name and field */ 657 if (namelen != 2) 658 return (ENOTDIR); /* overloaded */ 659 cdp = debugvars[name[0]]; 660 if (name[0] >= CTL_DEBUG_MAXID || cdp->debugname == 0) 661 return (EOPNOTSUPP); 662 switch (name[1]) { 663 case CTL_DEBUG_NAME: 664 return (sysctl_rdstring(oldp, oldlenp, newp, cdp->debugname)); 665 case CTL_DEBUG_VALUE: 666 return (sysctl_int(oldp, oldlenp, newp, newlen, cdp->debugvar)); 667 default: 668 return (EOPNOTSUPP); 669 } 670 /* NOTREACHED */ 671 } 672 #endif /* DEBUG */ 673 674 int 675 proc_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, 676 void *newp, size_t newlen, struct proc *p) 677 { 678 struct proc *ptmp = NULL; 679 const struct proclist_desc *pd; 680 int error = 0; 681 struct rlimit alim; 682 struct plimit *newplim; 683 char *tmps = NULL; 684 int i, curlen, len; 685 686 if (namelen < 2) 687 return EINVAL; 688 689 if (name[0] == PROC_CURPROC) { 690 ptmp = p; 691 } else { 692 proclist_lock_read(); 693 for (pd = proclists; pd->pd_list != NULL; pd++) { 694 for (ptmp = LIST_FIRST(pd->pd_list); ptmp != NULL; 695 ptmp = LIST_NEXT(ptmp, p_list)) { 696 /* Skip embryonic processes. */ 697 if (ptmp->p_stat == SIDL) 698 continue; 699 if (ptmp->p_pid == (pid_t)name[0]) 700 break; 701 } 702 if (ptmp != NULL) 703 break; 704 } 705 proclist_unlock_read(); 706 if (ptmp == NULL) 707 return(ESRCH); 708 if (p->p_ucred->cr_uid != 0) { 709 if(p->p_cred->p_ruid != ptmp->p_cred->p_ruid || 710 p->p_cred->p_ruid != ptmp->p_cred->p_svuid) 711 return EPERM; 712 if (ptmp->p_cred->p_rgid != ptmp->p_cred->p_svgid) 713 return EPERM; /* sgid proc */ 714 for (i = 0; i < p->p_ucred->cr_ngroups; i++) { 715 if (p->p_ucred->cr_groups[i] == 716 ptmp->p_cred->p_rgid) 717 break; 718 } 719 if (i == p->p_ucred->cr_ngroups) 720 return EPERM; 721 } 722 } 723 if (name[1] == PROC_PID_CORENAME) { 724 if (namelen != 2) 725 return EINVAL; 726 /* 727 * Can't use sysctl_string() here because we may malloc a new 728 * area during the process, so we have to do it by hand. 729 */ 730 curlen = strlen(ptmp->p_limit->pl_corename) + 1; 731 if (oldlenp && *oldlenp < curlen) { 732 if (!oldp) 733 *oldlenp = curlen; 734 return (ENOMEM); 735 } 736 if (newp) { 737 if (securelevel > 2) 738 return EPERM; 739 if (newlen > MAXPATHLEN) 740 return ENAMETOOLONG; 741 tmps = malloc(newlen + 1, M_TEMP, M_WAITOK); 742 if (tmps == NULL) 743 return ENOMEM; 744 error = copyin(newp, tmps, newlen + 1); 745 tmps[newlen] = '\0'; 746 if (error) 747 goto cleanup; 748 /* Enforce to be either 'core' for end with '.core' */ 749 if (newlen < 4) { /* c.o.r.e */ 750 error = EINVAL; 751 goto cleanup; 752 } 753 len = newlen - 4; 754 if (len > 0) { 755 if (tmps[len - 1] != '.' && 756 tmps[len - 1] != '/') { 757 error = EINVAL; 758 goto cleanup; 759 } 760 } 761 if (strcmp(&tmps[len], "core") != 0) { 762 error = EINVAL; 763 goto cleanup; 764 } 765 } 766 if (oldp && oldlenp) { 767 *oldlenp = curlen; 768 error = copyout(ptmp->p_limit->pl_corename, oldp, 769 curlen); 770 } 771 if (newp && error == 0) { 772 /* if the 2 strings are identical, don't limcopy() */ 773 if (strcmp(tmps, ptmp->p_limit->pl_corename) == 0) { 774 error = 0; 775 goto cleanup; 776 } 777 if (ptmp->p_limit->p_refcnt > 1 && 778 (ptmp->p_limit->p_lflags & PL_SHAREMOD) == 0) { 779 newplim = limcopy(ptmp->p_limit); 780 limfree(ptmp->p_limit); 781 ptmp->p_limit = newplim; 782 } 783 if (ptmp->p_limit->pl_corename != defcorename) { 784 free(ptmp->p_limit->pl_corename, M_TEMP); 785 } 786 ptmp->p_limit->pl_corename = tmps; 787 return (0); 788 } 789 cleanup: 790 if (tmps) 791 free(tmps, M_TEMP); 792 return (error); 793 } 794 if (name[1] == PROC_PID_LIMIT) { 795 if (namelen != 4 || name[2] >= PROC_PID_LIMIT_MAXID) 796 return EINVAL; 797 memcpy(&alim, &ptmp->p_rlimit[name[2] - 1], sizeof(alim)); 798 if (name[3] == PROC_PID_LIMIT_TYPE_HARD) 799 error = sysctl_quad(oldp, oldlenp, newp, newlen, 800 &alim.rlim_max); 801 else if (name[3] == PROC_PID_LIMIT_TYPE_SOFT) 802 error = sysctl_quad(oldp, oldlenp, newp, newlen, 803 &alim.rlim_cur); 804 else 805 error = EINVAL; 806 807 if (error) 808 return error; 809 810 if (newp) 811 error = dosetrlimit(ptmp, p->p_cred, 812 name[2] - 1, &alim); 813 return error; 814 } 815 return (EINVAL); 816 } 817 818 /* 819 * Convenience macros. 820 */ 821 822 #define SYSCTL_SCALAR_CORE_LEN(oldp, oldlenp, valp, len) \ 823 if (oldlenp) { \ 824 if (!oldp) \ 825 *oldlenp = len; \ 826 else { \ 827 if (*oldlenp < len) \ 828 return(ENOMEM); \ 829 *oldlenp = len; \ 830 error = copyout((caddr_t)valp, oldp, len); \ 831 } \ 832 } 833 834 #define SYSCTL_SCALAR_CORE_TYP(oldp, oldlenp, valp, typ) \ 835 SYSCTL_SCALAR_CORE_LEN(oldp, oldlenp, valp, sizeof(typ)) 836 837 #define SYSCTL_SCALAR_NEWPCHECK_LEN(newp, newlen, len) \ 838 if (newp && newlen != len) \ 839 return (EINVAL); 840 841 #define SYSCTL_SCALAR_NEWPCHECK_TYP(newp, newlen, typ) \ 842 SYSCTL_SCALAR_NEWPCHECK_LEN(newp, newlen, sizeof(typ)) 843 844 #define SYSCTL_SCALAR_NEWPCOP_LEN(newp, valp, len) \ 845 if (error == 0 && newp) \ 846 error = copyin(newp, valp, len); 847 848 #define SYSCTL_SCALAR_NEWPCOP_TYP(newp, valp, typ) \ 849 SYSCTL_SCALAR_NEWPCOP_LEN(newp, valp, sizeof(typ)) 850 851 #define SYSCTL_STRING_CORE(oldp, oldlenp, str) \ 852 if (oldlenp) { \ 853 len = strlen(str) + 1; \ 854 if (!oldp) \ 855 *oldlenp = len; \ 856 else { \ 857 if (*oldlenp < len) { \ 858 err2 = ENOMEM; \ 859 len = *oldlenp; \ 860 } else \ 861 *oldlenp = len; \ 862 error = copyout(str, oldp, len);\ 863 if (error == 0) \ 864 error = err2; \ 865 } \ 866 } 867 868 /* 869 * Validate parameters and get old / set new parameters 870 * for an integer-valued sysctl function. 871 */ 872 int 873 sysctl_int(void *oldp, size_t *oldlenp, void *newp, size_t newlen, int *valp) 874 { 875 int error = 0; 876 877 SYSCTL_SCALAR_NEWPCHECK_TYP(newp, newlen, int) 878 SYSCTL_SCALAR_CORE_TYP(oldp, oldlenp, valp, int) 879 SYSCTL_SCALAR_NEWPCOP_TYP(newp, valp, int) 880 881 return (error); 882 } 883 884 885 /* 886 * As above, but read-only. 887 */ 888 int 889 sysctl_rdint(void *oldp, size_t *oldlenp, void *newp, int val) 890 { 891 int error = 0; 892 893 if (newp) 894 return (EPERM); 895 896 SYSCTL_SCALAR_CORE_TYP(oldp, oldlenp, &val, int) 897 898 return (error); 899 } 900 901 /* 902 * Validate parameters and get old / set new parameters 903 * for an quad-valued sysctl function. 904 */ 905 int 906 sysctl_quad(void *oldp, size_t *oldlenp, void *newp, size_t newlen, 907 quad_t *valp) 908 { 909 int error = 0; 910 911 SYSCTL_SCALAR_NEWPCHECK_TYP(newp, newlen, quad_t) 912 SYSCTL_SCALAR_CORE_TYP(oldp, oldlenp, valp, quad_t) 913 SYSCTL_SCALAR_NEWPCOP_TYP(newp, valp, quad_t) 914 915 return (error); 916 } 917 918 /* 919 * As above, but read-only. 920 */ 921 int 922 sysctl_rdquad(void *oldp, size_t *oldlenp, void *newp, quad_t val) 923 { 924 int error = 0; 925 926 if (newp) 927 return (EPERM); 928 929 SYSCTL_SCALAR_CORE_TYP(oldp, oldlenp, &val, quad_t) 930 931 return (error); 932 } 933 934 /* 935 * Validate parameters and get old / set new parameters 936 * for a string-valued sysctl function. 937 */ 938 int 939 sysctl_string(void *oldp, size_t *oldlenp, void *newp, size_t newlen, char *str, 940 int maxlen) 941 { 942 int len, error = 0, err2 = 0; 943 944 if (newp && newlen >= maxlen) 945 return (EINVAL); 946 947 SYSCTL_STRING_CORE(oldp, oldlenp, str); 948 949 if (error == 0 && newp) { 950 error = copyin(newp, str, newlen); 951 str[newlen] = 0; 952 } 953 return (error); 954 } 955 956 /* 957 * As above, but read-only. 958 */ 959 int 960 sysctl_rdstring(void *oldp, size_t *oldlenp, void *newp, const char *str) 961 { 962 int len, error = 0, err2 = 0; 963 964 if (newp) 965 return (EPERM); 966 967 SYSCTL_STRING_CORE(oldp, oldlenp, str); 968 969 return (error); 970 } 971 972 /* 973 * Validate parameters and get old / set new parameters 974 * for a structure oriented sysctl function. 975 */ 976 int 977 sysctl_struct(void *oldp, size_t *oldlenp, void *newp, size_t newlen, void *sp, 978 int len) 979 { 980 int error = 0; 981 982 SYSCTL_SCALAR_NEWPCHECK_LEN(newp, newlen, len) 983 SYSCTL_SCALAR_CORE_LEN(oldp, oldlenp, sp, len) 984 SYSCTL_SCALAR_NEWPCOP_LEN(newp, sp, len) 985 986 return (error); 987 } 988 989 /* 990 * Validate parameters and get old parameters 991 * for a structure oriented sysctl function. 992 */ 993 int 994 sysctl_rdstruct(void *oldp, size_t *oldlenp, void *newp, const void *sp, 995 int len) 996 { 997 int error = 0; 998 999 if (newp) 1000 return (EPERM); 1001 1002 SYSCTL_SCALAR_CORE_LEN(oldp, oldlenp, sp, len) 1003 1004 return (error); 1005 } 1006 1007 /* 1008 * As above, but can return a truncated result. 1009 */ 1010 int 1011 sysctl_rdminstruct(void *oldp, size_t *oldlenp, void *newp, const void *sp, 1012 int len) 1013 { 1014 int error = 0; 1015 1016 if (newp) 1017 return (EPERM); 1018 1019 len = min(*oldlenp, len); 1020 SYSCTL_SCALAR_CORE_LEN(oldp, oldlenp, sp, len) 1021 1022 return (error); 1023 } 1024 1025 /* 1026 * Get file structures. 1027 */ 1028 static int 1029 sysctl_file(void *vwhere, size_t *sizep) 1030 { 1031 int buflen, error; 1032 struct file *fp; 1033 char *start, *where; 1034 1035 start = where = vwhere; 1036 buflen = *sizep; 1037 if (where == NULL) { 1038 /* 1039 * overestimate by 10 files 1040 */ 1041 *sizep = sizeof(filehead) + (nfiles + 10) * sizeof(struct file); 1042 return (0); 1043 } 1044 1045 /* 1046 * first copyout filehead 1047 */ 1048 if (buflen < sizeof(filehead)) { 1049 *sizep = 0; 1050 return (0); 1051 } 1052 error = copyout((caddr_t)&filehead, where, sizeof(filehead)); 1053 if (error) 1054 return (error); 1055 buflen -= sizeof(filehead); 1056 where += sizeof(filehead); 1057 1058 /* 1059 * followed by an array of file structures 1060 */ 1061 for (fp = filehead.lh_first; fp != 0; fp = fp->f_list.le_next) { 1062 if (buflen < sizeof(struct file)) { 1063 *sizep = where - start; 1064 return (ENOMEM); 1065 } 1066 error = copyout((caddr_t)fp, where, sizeof(struct file)); 1067 if (error) 1068 return (error); 1069 buflen -= sizeof(struct file); 1070 where += sizeof(struct file); 1071 } 1072 *sizep = where - start; 1073 return (0); 1074 } 1075 1076 #if defined(SYSVMSG) || defined(SYSVSEM) || defined(SYSVSHM) 1077 #define FILL_PERM(src, dst) do { \ 1078 (dst)._key = (src)._key; \ 1079 (dst).uid = (src).uid; \ 1080 (dst).gid = (src).gid; \ 1081 (dst).cuid = (src).cuid; \ 1082 (dst).cgid = (src).cgid; \ 1083 (dst).mode = (src).mode; \ 1084 (dst)._seq = (src)._seq; \ 1085 } while (0); 1086 #define FILL_MSG(src, dst) do { \ 1087 FILL_PERM((src).msg_perm, (dst).msg_perm); \ 1088 (dst).msg_qnum = (src).msg_qnum; \ 1089 (dst).msg_qbytes = (src).msg_qbytes; \ 1090 (dst)._msg_cbytes = (src)._msg_cbytes; \ 1091 (dst).msg_lspid = (src).msg_lspid; \ 1092 (dst).msg_lrpid = (src).msg_lrpid; \ 1093 (dst).msg_stime = (src).msg_stime; \ 1094 (dst).msg_rtime = (src).msg_rtime; \ 1095 (dst).msg_ctime = (src).msg_ctime; \ 1096 } while (0) 1097 #define FILL_SEM(src, dst) do { \ 1098 FILL_PERM((src).sem_perm, (dst).sem_perm); \ 1099 (dst).sem_nsems = (src).sem_nsems; \ 1100 (dst).sem_otime = (src).sem_otime; \ 1101 (dst).sem_ctime = (src).sem_ctime; \ 1102 } while (0) 1103 #define FILL_SHM(src, dst) do { \ 1104 FILL_PERM((src).shm_perm, (dst).shm_perm); \ 1105 (dst).shm_segsz = (src).shm_segsz; \ 1106 (dst).shm_lpid = (src).shm_lpid; \ 1107 (dst).shm_cpid = (src).shm_cpid; \ 1108 (dst).shm_atime = (src).shm_atime; \ 1109 (dst).shm_dtime = (src).shm_dtime; \ 1110 (dst).shm_ctime = (src).shm_ctime; \ 1111 (dst).shm_nattch = (src).shm_nattch; \ 1112 } while (0) 1113 1114 static int 1115 sysctl_sysvipc(int *name, u_int namelen, void *where, size_t *sizep) 1116 { 1117 #ifdef SYSVMSG 1118 struct msg_sysctl_info *msgsi; 1119 #endif 1120 #ifdef SYSVSEM 1121 struct sem_sysctl_info *semsi; 1122 #endif 1123 #ifdef SYSVSHM 1124 struct shm_sysctl_info *shmsi; 1125 #endif 1126 size_t infosize, dssize, tsize, buflen; 1127 void *buf = NULL, *buf2; 1128 char *start; 1129 int32_t nds; 1130 int i, error, ret; 1131 1132 if (namelen != 1) 1133 return (EINVAL); 1134 1135 start = where; 1136 buflen = *sizep; 1137 1138 switch (*name) { 1139 case KERN_SYSVIPC_MSG_INFO: 1140 #ifdef SYSVMSG 1141 infosize = sizeof(msgsi->msginfo); 1142 nds = msginfo.msgmni; 1143 dssize = sizeof(msgsi->msgids[0]); 1144 break; 1145 #else 1146 return (EINVAL); 1147 #endif 1148 case KERN_SYSVIPC_SEM_INFO: 1149 #ifdef SYSVSEM 1150 infosize = sizeof(semsi->seminfo); 1151 nds = seminfo.semmni; 1152 dssize = sizeof(semsi->semids[0]); 1153 break; 1154 #else 1155 return (EINVAL); 1156 #endif 1157 case KERN_SYSVIPC_SHM_INFO: 1158 #ifdef SYSVSHM 1159 infosize = sizeof(shmsi->shminfo); 1160 nds = shminfo.shmmni; 1161 dssize = sizeof(shmsi->shmids[0]); 1162 break; 1163 #else 1164 return (EINVAL); 1165 #endif 1166 default: 1167 return (EINVAL); 1168 } 1169 /* 1170 * Round infosize to 64 bit boundary if requesting more than just 1171 * the info structure or getting the total data size. 1172 */ 1173 if (where == NULL || *sizep > infosize) 1174 infosize = ((infosize + 7) / 8) * 8; 1175 tsize = infosize + nds * dssize; 1176 1177 /* Return just the total size required. */ 1178 if (where == NULL) { 1179 *sizep = tsize; 1180 return (0); 1181 } 1182 1183 /* Not enough room for even the info struct. */ 1184 if (buflen < infosize) { 1185 *sizep = 0; 1186 return (ENOMEM); 1187 } 1188 buf = malloc(min(tsize, buflen), M_TEMP, M_WAITOK); 1189 memset(buf, 0, min(tsize, buflen)); 1190 1191 switch (*name) { 1192 #ifdef SYSVMSG 1193 case KERN_SYSVIPC_MSG_INFO: 1194 msgsi = (struct msg_sysctl_info *)buf; 1195 buf2 = &msgsi->msgids[0]; 1196 msgsi->msginfo = msginfo; 1197 break; 1198 #endif 1199 #ifdef SYSVSEM 1200 case KERN_SYSVIPC_SEM_INFO: 1201 semsi = (struct sem_sysctl_info *)buf; 1202 buf2 = &semsi->semids[0]; 1203 semsi->seminfo = seminfo; 1204 break; 1205 #endif 1206 #ifdef SYSVSHM 1207 case KERN_SYSVIPC_SHM_INFO: 1208 shmsi = (struct shm_sysctl_info *)buf; 1209 buf2 = &shmsi->shmids[0]; 1210 shmsi->shminfo = shminfo; 1211 break; 1212 #endif 1213 } 1214 buflen -= infosize; 1215 1216 ret = 0; 1217 if (buflen > 0) { 1218 /* Fill in the IPC data structures. */ 1219 for (i = 0; i < nds; i++) { 1220 if (buflen < dssize) { 1221 ret = ENOMEM; 1222 break; 1223 } 1224 switch (*name) { 1225 #ifdef SYSVMSG 1226 case KERN_SYSVIPC_MSG_INFO: 1227 FILL_MSG(msqids[i], msgsi->msgids[i]); 1228 break; 1229 #endif 1230 #ifdef SYSVSEM 1231 case KERN_SYSVIPC_SEM_INFO: 1232 FILL_SEM(sema[i], semsi->semids[i]); 1233 break; 1234 #endif 1235 #ifdef SYSVSHM 1236 case KERN_SYSVIPC_SHM_INFO: 1237 FILL_SHM(shmsegs[i], shmsi->shmids[i]); 1238 break; 1239 #endif 1240 } 1241 buflen -= dssize; 1242 } 1243 } 1244 *sizep -= buflen; 1245 error = copyout(buf, start, *sizep); 1246 /* If copyout succeeded, use return code set earlier. */ 1247 if (error == 0) 1248 error = ret; 1249 if (buf) 1250 free(buf, M_TEMP); 1251 return (error); 1252 } 1253 #endif /* SYSVMSG || SYSVSEM || SYSVSHM */ 1254 1255 static int 1256 sysctl_msgbuf(void *vwhere, size_t *sizep) 1257 { 1258 char *where = vwhere; 1259 size_t len, maxlen = *sizep; 1260 long beg, end; 1261 int error; 1262 1263 /* 1264 * deal with cases where the message buffer has 1265 * become corrupted. 1266 */ 1267 if (!msgbufenabled || msgbufp->msg_magic != MSG_MAGIC) { 1268 msgbufenabled = 0; 1269 return (ENXIO); 1270 } 1271 1272 if (where == NULL) { 1273 /* always return full buffer size */ 1274 *sizep = msgbufp->msg_bufs; 1275 return (0); 1276 } 1277 1278 error = 0; 1279 maxlen = min(msgbufp->msg_bufs, maxlen); 1280 1281 /* 1282 * First, copy from the write pointer to the end of 1283 * message buffer. 1284 */ 1285 beg = msgbufp->msg_bufx; 1286 end = msgbufp->msg_bufs; 1287 while (maxlen > 0) { 1288 len = min(end - beg, maxlen); 1289 if (len == 0) 1290 break; 1291 error = copyout(&msgbufp->msg_bufc[beg], where, len); 1292 if (error) 1293 break; 1294 where += len; 1295 maxlen -= len; 1296 1297 /* 1298 * ... then, copy from the beginning of message buffer to 1299 * the write pointer. 1300 */ 1301 beg = 0; 1302 end = msgbufp->msg_bufx; 1303 } 1304 return (error); 1305 } 1306 1307 /* 1308 * try over estimating by 5 procs 1309 */ 1310 #define KERN_PROCSLOP (5 * sizeof(struct kinfo_proc)) 1311 1312 static int 1313 sysctl_doeproc(int *name, u_int namelen, void *vwhere, size_t *sizep) 1314 { 1315 struct eproc eproc; 1316 struct kinfo_proc2 kproc2; 1317 struct kinfo_proc *dp; 1318 struct proc *p; 1319 const struct proclist_desc *pd; 1320 char *where, *dp2; 1321 int type, op, arg, elem_size, elem_count; 1322 int buflen, needed, error; 1323 1324 dp = vwhere; 1325 dp2 = where = vwhere; 1326 buflen = where != NULL ? *sizep : 0; 1327 error = needed = 0; 1328 type = name[0]; 1329 1330 if (type == KERN_PROC) { 1331 if (namelen != 3 && !(namelen == 2 && name[1] == KERN_PROC_ALL)) 1332 return (EINVAL); 1333 op = name[1]; 1334 if (op != KERN_PROC_ALL) 1335 arg = name[2]; 1336 } else { 1337 if (namelen != 5) 1338 return (EINVAL); 1339 op = name[1]; 1340 arg = name[2]; 1341 elem_size = name[3]; 1342 elem_count = name[4]; 1343 } 1344 1345 proclist_lock_read(); 1346 1347 pd = proclists; 1348 again: 1349 for (p = LIST_FIRST(pd->pd_list); p != NULL; p = LIST_NEXT(p, p_list)) { 1350 /* 1351 * Skip embryonic processes. 1352 */ 1353 if (p->p_stat == SIDL) 1354 continue; 1355 /* 1356 * TODO - make more efficient (see notes below). 1357 * do by session. 1358 */ 1359 switch (op) { 1360 1361 case KERN_PROC_PID: 1362 /* could do this with just a lookup */ 1363 if (p->p_pid != (pid_t)arg) 1364 continue; 1365 break; 1366 1367 case KERN_PROC_PGRP: 1368 /* could do this by traversing pgrp */ 1369 if (p->p_pgrp->pg_id != (pid_t)arg) 1370 continue; 1371 break; 1372 1373 case KERN_PROC_SESSION: 1374 if (p->p_session->s_sid != (pid_t)arg) 1375 continue; 1376 break; 1377 1378 case KERN_PROC_TTY: 1379 if (arg == KERN_PROC_TTY_REVOKE) { 1380 if ((p->p_flag & P_CONTROLT) == 0 || 1381 p->p_session->s_ttyp == NULL || 1382 p->p_session->s_ttyvp != NULL) 1383 continue; 1384 } else if ((p->p_flag & P_CONTROLT) == 0 || 1385 p->p_session->s_ttyp == NULL) { 1386 if ((dev_t)arg != KERN_PROC_TTY_NODEV) 1387 continue; 1388 } else if (p->p_session->s_ttyp->t_dev != (dev_t)arg) 1389 continue; 1390 break; 1391 1392 case KERN_PROC_UID: 1393 if (p->p_ucred->cr_uid != (uid_t)arg) 1394 continue; 1395 break; 1396 1397 case KERN_PROC_RUID: 1398 if (p->p_cred->p_ruid != (uid_t)arg) 1399 continue; 1400 break; 1401 1402 case KERN_PROC_GID: 1403 if (p->p_ucred->cr_gid != (uid_t)arg) 1404 continue; 1405 break; 1406 1407 case KERN_PROC_RGID: 1408 if (p->p_cred->p_rgid != (uid_t)arg) 1409 continue; 1410 break; 1411 1412 case KERN_PROC_ALL: 1413 /* allow everything */ 1414 break; 1415 1416 default: 1417 error = EINVAL; 1418 goto cleanup; 1419 } 1420 if (type == KERN_PROC) { 1421 if (buflen >= sizeof(struct kinfo_proc)) { 1422 fill_eproc(p, &eproc); 1423 error = copyout((caddr_t)p, &dp->kp_proc, 1424 sizeof(struct proc)); 1425 if (error) 1426 goto cleanup; 1427 error = copyout((caddr_t)&eproc, &dp->kp_eproc, 1428 sizeof(eproc)); 1429 if (error) 1430 goto cleanup; 1431 dp++; 1432 buflen -= sizeof(struct kinfo_proc); 1433 } 1434 needed += sizeof(struct kinfo_proc); 1435 } else { /* KERN_PROC2 */ 1436 if (buflen >= elem_size && elem_count > 0) { 1437 fill_kproc2(p, &kproc2); 1438 /* 1439 * Copy out elem_size, but not larger than 1440 * the size of a struct kinfo_proc2. 1441 */ 1442 error = copyout(&kproc2, dp2, 1443 min(sizeof(kproc2), elem_size)); 1444 if (error) 1445 goto cleanup; 1446 dp2 += elem_size; 1447 buflen -= elem_size; 1448 elem_count--; 1449 } 1450 needed += elem_size; 1451 } 1452 } 1453 pd++; 1454 if (pd->pd_list != NULL) 1455 goto again; 1456 proclist_unlock_read(); 1457 1458 if (where != NULL) { 1459 if (type == KERN_PROC) 1460 *sizep = (caddr_t)dp - where; 1461 else 1462 *sizep = dp2 - where; 1463 if (needed > *sizep) 1464 return (ENOMEM); 1465 } else { 1466 needed += KERN_PROCSLOP; 1467 *sizep = needed; 1468 } 1469 return (0); 1470 cleanup: 1471 proclist_unlock_read(); 1472 return (error); 1473 } 1474 1475 /* 1476 * Fill in an eproc structure for the specified process. 1477 */ 1478 void 1479 fill_eproc(struct proc *p, struct eproc *ep) 1480 { 1481 struct tty *tp; 1482 1483 ep->e_paddr = p; 1484 ep->e_sess = p->p_session; 1485 ep->e_pcred = *p->p_cred; 1486 ep->e_ucred = *p->p_ucred; 1487 if (p->p_stat == SIDL || P_ZOMBIE(p)) { 1488 ep->e_vm.vm_rssize = 0; 1489 ep->e_vm.vm_tsize = 0; 1490 ep->e_vm.vm_dsize = 0; 1491 ep->e_vm.vm_ssize = 0; 1492 /* ep->e_vm.vm_pmap = XXX; */ 1493 } else { 1494 struct vmspace *vm = p->p_vmspace; 1495 1496 ep->e_vm.vm_rssize = vm_resident_count(vm); 1497 ep->e_vm.vm_tsize = vm->vm_tsize; 1498 ep->e_vm.vm_dsize = vm->vm_dsize; 1499 ep->e_vm.vm_ssize = vm->vm_ssize; 1500 } 1501 if (p->p_pptr) 1502 ep->e_ppid = p->p_pptr->p_pid; 1503 else 1504 ep->e_ppid = 0; 1505 ep->e_pgid = p->p_pgrp->pg_id; 1506 ep->e_sid = ep->e_sess->s_sid; 1507 ep->e_jobc = p->p_pgrp->pg_jobc; 1508 if ((p->p_flag & P_CONTROLT) && 1509 (tp = ep->e_sess->s_ttyp)) { 1510 ep->e_tdev = tp->t_dev; 1511 ep->e_tpgid = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID; 1512 ep->e_tsess = tp->t_session; 1513 } else 1514 ep->e_tdev = NODEV; 1515 if (p->p_wmesg) 1516 strncpy(ep->e_wmesg, p->p_wmesg, WMESGLEN); 1517 ep->e_xsize = ep->e_xrssize = 0; 1518 ep->e_xccount = ep->e_xswrss = 0; 1519 ep->e_flag = ep->e_sess->s_ttyvp ? EPROC_CTTY : 0; 1520 if (SESS_LEADER(p)) 1521 ep->e_flag |= EPROC_SLEADER; 1522 strncpy(ep->e_login, ep->e_sess->s_login, MAXLOGNAME); 1523 } 1524 1525 /* 1526 * Fill in an eproc structure for the specified process. 1527 */ 1528 static void 1529 fill_kproc2(struct proc *p, struct kinfo_proc2 *ki) 1530 { 1531 struct tty *tp; 1532 1533 memset(ki, 0, sizeof(*ki)); 1534 1535 ki->p_forw = PTRTOINT64(p->p_forw); 1536 ki->p_back = PTRTOINT64(p->p_back); 1537 ki->p_paddr = PTRTOINT64(p); 1538 1539 ki->p_addr = PTRTOINT64(p->p_addr); 1540 ki->p_fd = PTRTOINT64(p->p_fd); 1541 ki->p_cwdi = PTRTOINT64(p->p_cwdi); 1542 ki->p_stats = PTRTOINT64(p->p_stats); 1543 ki->p_limit = PTRTOINT64(p->p_limit); 1544 ki->p_vmspace = PTRTOINT64(p->p_vmspace); 1545 ki->p_sigacts = PTRTOINT64(p->p_sigacts); 1546 ki->p_sess = PTRTOINT64(p->p_session); 1547 ki->p_tsess = 0; /* may be changed if controlling tty below */ 1548 ki->p_ru = PTRTOINT64(p->p_ru); 1549 1550 ki->p_eflag = 0; 1551 ki->p_exitsig = p->p_exitsig; 1552 ki->p_flag = p->p_flag; 1553 1554 ki->p_pid = p->p_pid; 1555 if (p->p_pptr) 1556 ki->p_ppid = p->p_pptr->p_pid; 1557 else 1558 ki->p_ppid = 0; 1559 ki->p_sid = p->p_session->s_sid; 1560 ki->p__pgid = p->p_pgrp->pg_id; 1561 1562 ki->p_tpgid = NO_PID; /* may be changed if controlling tty below */ 1563 1564 ki->p_uid = p->p_ucred->cr_uid; 1565 ki->p_ruid = p->p_cred->p_ruid; 1566 ki->p_gid = p->p_ucred->cr_gid; 1567 ki->p_rgid = p->p_cred->p_rgid; 1568 1569 memcpy(ki->p_groups, p->p_cred->pc_ucred->cr_groups, 1570 min(sizeof(ki->p_groups), sizeof(p->p_cred->pc_ucred->cr_groups))); 1571 ki->p_ngroups = p->p_cred->pc_ucred->cr_ngroups; 1572 1573 ki->p_jobc = p->p_pgrp->pg_jobc; 1574 if ((p->p_flag & P_CONTROLT) && (tp = p->p_session->s_ttyp)) { 1575 ki->p_tdev = tp->t_dev; 1576 ki->p_tpgid = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID; 1577 ki->p_tsess = PTRTOINT64(tp->t_session); 1578 } else { 1579 ki->p_tdev = NODEV; 1580 } 1581 1582 ki->p_estcpu = p->p_estcpu; 1583 ki->p_rtime_sec = p->p_rtime.tv_sec; 1584 ki->p_rtime_usec = p->p_rtime.tv_usec; 1585 ki->p_cpticks = p->p_cpticks; 1586 ki->p_pctcpu = p->p_pctcpu; 1587 ki->p_swtime = p->p_swtime; 1588 ki->p_slptime = p->p_slptime; 1589 if (p->p_stat == SONPROC) { 1590 KDASSERT(p->p_cpu != NULL); 1591 ki->p_schedflags = p->p_cpu->ci_schedstate.spc_flags; 1592 } else 1593 ki->p_schedflags = 0; 1594 1595 ki->p_uticks = p->p_uticks; 1596 ki->p_sticks = p->p_sticks; 1597 ki->p_iticks = p->p_iticks; 1598 1599 ki->p_tracep = PTRTOINT64(p->p_tracep); 1600 ki->p_traceflag = p->p_traceflag; 1601 1602 ki->p_holdcnt = p->p_holdcnt; 1603 1604 memcpy(&ki->p_siglist, &p->p_sigctx.ps_siglist, sizeof(ki_sigset_t)); 1605 memcpy(&ki->p_sigmask, &p->p_sigctx.ps_sigmask, sizeof(ki_sigset_t)); 1606 memcpy(&ki->p_sigignore, &p->p_sigctx.ps_sigignore,sizeof(ki_sigset_t)); 1607 memcpy(&ki->p_sigcatch, &p->p_sigctx.ps_sigcatch, sizeof(ki_sigset_t)); 1608 1609 ki->p_stat = p->p_stat; 1610 ki->p_priority = p->p_priority; 1611 ki->p_usrpri = p->p_usrpri; 1612 ki->p_nice = p->p_nice; 1613 1614 ki->p_xstat = p->p_xstat; 1615 ki->p_acflag = p->p_acflag; 1616 1617 strncpy(ki->p_comm, p->p_comm, 1618 min(sizeof(ki->p_comm), sizeof(p->p_comm))); 1619 1620 if (p->p_wmesg) 1621 strncpy(ki->p_wmesg, p->p_wmesg, sizeof(ki->p_wmesg)); 1622 ki->p_wchan = PTRTOINT64(p->p_wchan); 1623 1624 strncpy(ki->p_login, p->p_session->s_login, sizeof(ki->p_login)); 1625 1626 if (p->p_stat == SIDL || P_ZOMBIE(p)) { 1627 ki->p_vm_rssize = 0; 1628 ki->p_vm_tsize = 0; 1629 ki->p_vm_dsize = 0; 1630 ki->p_vm_ssize = 0; 1631 } else { 1632 struct vmspace *vm = p->p_vmspace; 1633 1634 ki->p_vm_rssize = vm_resident_count(vm); 1635 ki->p_vm_tsize = vm->vm_tsize; 1636 ki->p_vm_dsize = vm->vm_dsize; 1637 ki->p_vm_ssize = vm->vm_ssize; 1638 } 1639 1640 if (p->p_session->s_ttyvp) 1641 ki->p_eflag |= EPROC_CTTY; 1642 if (SESS_LEADER(p)) 1643 ki->p_eflag |= EPROC_SLEADER; 1644 1645 /* XXX Is this double check necessary? */ 1646 if ((p->p_flag & P_INMEM) == 0 || P_ZOMBIE(p)) { 1647 ki->p_uvalid = 0; 1648 } else { 1649 ki->p_uvalid = 1; 1650 1651 ki->p_ustart_sec = p->p_stats->p_start.tv_sec; 1652 ki->p_ustart_usec = p->p_stats->p_start.tv_usec; 1653 1654 ki->p_uutime_sec = p->p_stats->p_ru.ru_utime.tv_sec; 1655 ki->p_uutime_usec = p->p_stats->p_ru.ru_utime.tv_usec; 1656 ki->p_ustime_sec = p->p_stats->p_ru.ru_stime.tv_sec; 1657 ki->p_ustime_usec = p->p_stats->p_ru.ru_stime.tv_usec; 1658 1659 ki->p_uru_maxrss = p->p_stats->p_ru.ru_maxrss; 1660 ki->p_uru_ixrss = p->p_stats->p_ru.ru_ixrss; 1661 ki->p_uru_idrss = p->p_stats->p_ru.ru_idrss; 1662 ki->p_uru_isrss = p->p_stats->p_ru.ru_isrss; 1663 ki->p_uru_minflt = p->p_stats->p_ru.ru_minflt; 1664 ki->p_uru_majflt = p->p_stats->p_ru.ru_majflt; 1665 ki->p_uru_nswap = p->p_stats->p_ru.ru_nswap; 1666 ki->p_uru_inblock = p->p_stats->p_ru.ru_inblock; 1667 ki->p_uru_oublock = p->p_stats->p_ru.ru_oublock; 1668 ki->p_uru_msgsnd = p->p_stats->p_ru.ru_msgsnd; 1669 ki->p_uru_msgrcv = p->p_stats->p_ru.ru_msgrcv; 1670 ki->p_uru_nsignals = p->p_stats->p_ru.ru_nsignals; 1671 ki->p_uru_nvcsw = p->p_stats->p_ru.ru_nvcsw; 1672 ki->p_uru_nivcsw = p->p_stats->p_ru.ru_nivcsw; 1673 1674 ki->p_uctime_sec = p->p_stats->p_cru.ru_utime.tv_sec + 1675 p->p_stats->p_cru.ru_stime.tv_sec; 1676 ki->p_uctime_usec = p->p_stats->p_cru.ru_utime.tv_usec + 1677 p->p_stats->p_cru.ru_stime.tv_usec; 1678 } 1679 #ifdef MULTIPROCESSOR 1680 if (p->p_cpu != NULL) 1681 ki->p_cpuid = p->p_cpu->ci_cpuid; 1682 else 1683 #endif 1684 ki->p_cpuid = KI_NOCPU; 1685 } 1686 1687 int 1688 sysctl_procargs(int *name, u_int namelen, void *where, size_t *sizep, 1689 struct proc *up) 1690 { 1691 struct ps_strings pss; 1692 struct proc *p; 1693 size_t len, upper_bound, xlen; 1694 struct uio auio; 1695 struct iovec aiov; 1696 vaddr_t argv; 1697 pid_t pid; 1698 int nargv, type, error, i; 1699 char *arg; 1700 char *tmp; 1701 1702 if (namelen != 2) 1703 return (EINVAL); 1704 pid = name[0]; 1705 type = name[1]; 1706 1707 switch (type) { 1708 case KERN_PROC_ARGV: 1709 case KERN_PROC_NARGV: 1710 case KERN_PROC_ENV: 1711 case KERN_PROC_NENV: 1712 /* ok */ 1713 break; 1714 default: 1715 return (EINVAL); 1716 } 1717 1718 /* check pid */ 1719 if ((p = pfind(pid)) == NULL) 1720 return (EINVAL); 1721 1722 /* only root or same user change look at the environment */ 1723 if (type == KERN_PROC_ENV || type == KERN_PROC_NENV) { 1724 if (up->p_ucred->cr_uid != 0) { 1725 if (up->p_cred->p_ruid != p->p_cred->p_ruid || 1726 up->p_cred->p_ruid != p->p_cred->p_svuid) 1727 return (EPERM); 1728 } 1729 } 1730 1731 if (sizep != NULL && where == NULL) { 1732 if (type == KERN_PROC_NARGV || type == KERN_PROC_NENV) 1733 *sizep = sizeof (int); 1734 else 1735 *sizep = ARG_MAX; /* XXX XXX XXX */ 1736 return (0); 1737 } 1738 if (where == NULL || sizep == NULL) 1739 return (EINVAL); 1740 1741 /* 1742 * Zombies don't have a stack, so we can't read their psstrings. 1743 * System processes also don't have a user stack. 1744 */ 1745 if (P_ZOMBIE(p) || (p->p_flag & P_SYSTEM) != 0) 1746 return (EINVAL); 1747 1748 /* 1749 * Lock the process down in memory. 1750 */ 1751 /* XXXCDC: how should locking work here? */ 1752 if ((p->p_flag & P_WEXIT) || (p->p_vmspace->vm_refcnt < 1)) 1753 return (EFAULT); 1754 p->p_vmspace->vm_refcnt++; /* XXX */ 1755 1756 /* 1757 * Allocate a temporary buffer to hold the arguments. 1758 */ 1759 arg = malloc(PAGE_SIZE, M_TEMP, M_WAITOK); 1760 1761 /* 1762 * Read in the ps_strings structure. 1763 */ 1764 aiov.iov_base = &pss; 1765 aiov.iov_len = sizeof(pss); 1766 auio.uio_iov = &aiov; 1767 auio.uio_iovcnt = 1; 1768 auio.uio_offset = (vaddr_t)p->p_psstr; 1769 auio.uio_resid = sizeof(pss); 1770 auio.uio_segflg = UIO_SYSSPACE; 1771 auio.uio_rw = UIO_READ; 1772 auio.uio_procp = NULL; 1773 error = uvm_io(&p->p_vmspace->vm_map, &auio); 1774 if (error) 1775 goto done; 1776 1777 if (type == KERN_PROC_ARGV || type == KERN_PROC_NARGV) 1778 memcpy(&nargv, (char *)&pss + p->p_psnargv, sizeof(nargv)); 1779 else 1780 memcpy(&nargv, (char *)&pss + p->p_psnenv, sizeof(nargv)); 1781 if (type == KERN_PROC_NARGV || type == KERN_PROC_NENV) { 1782 error = copyout(&nargv, where, sizeof(nargv)); 1783 *sizep = sizeof(nargv); 1784 goto done; 1785 } 1786 /* 1787 * Now read the address of the argument vector. 1788 */ 1789 switch (type) { 1790 case KERN_PROC_ARGV: 1791 /* XXX compat32 stuff here */ 1792 memcpy(&tmp, (char *)&pss + p->p_psargv, sizeof(tmp)); 1793 break; 1794 case KERN_PROC_ENV: 1795 memcpy(&tmp, (char *)&pss + p->p_psenv, sizeof(tmp)); 1796 break; 1797 default: 1798 return (EINVAL); 1799 } 1800 auio.uio_offset = (off_t)(long)tmp; 1801 aiov.iov_base = &argv; 1802 aiov.iov_len = sizeof(argv); 1803 auio.uio_iov = &aiov; 1804 auio.uio_iovcnt = 1; 1805 auio.uio_resid = sizeof(argv); 1806 auio.uio_segflg = UIO_SYSSPACE; 1807 auio.uio_rw = UIO_READ; 1808 auio.uio_procp = NULL; 1809 error = uvm_io(&p->p_vmspace->vm_map, &auio); 1810 if (error) 1811 goto done; 1812 1813 /* 1814 * Now copy in the actual argument vector, one page at a time, 1815 * since we don't know how long the vector is (though, we do 1816 * know how many NUL-terminated strings are in the vector). 1817 */ 1818 len = 0; 1819 upper_bound = *sizep; 1820 for (; nargv != 0 && len < upper_bound; len += xlen) { 1821 aiov.iov_base = arg; 1822 aiov.iov_len = PAGE_SIZE; 1823 auio.uio_iov = &aiov; 1824 auio.uio_iovcnt = 1; 1825 auio.uio_offset = argv + len; 1826 xlen = PAGE_SIZE - ((argv + len) & PAGE_MASK); 1827 auio.uio_resid = xlen; 1828 auio.uio_segflg = UIO_SYSSPACE; 1829 auio.uio_rw = UIO_READ; 1830 auio.uio_procp = NULL; 1831 error = uvm_io(&p->p_vmspace->vm_map, &auio); 1832 if (error) 1833 goto done; 1834 1835 for (i = 0; i < xlen && nargv != 0; i++) { 1836 if (arg[i] == '\0') 1837 nargv--; /* one full string */ 1838 } 1839 1840 /* make sure we don't copyout past the end of the user's buffer */ 1841 if (len + i > upper_bound) 1842 i = upper_bound - len; 1843 1844 error = copyout(arg, (char *)where + len, i); 1845 if (error) 1846 break; 1847 1848 if (nargv == 0) { 1849 len += i; 1850 break; 1851 } 1852 } 1853 *sizep = len; 1854 1855 done: 1856 uvmspace_free(p->p_vmspace); 1857 1858 free(arg, M_TEMP); 1859 return (error); 1860 } 1861 1862 #if NPTY > 0 1863 int pty_maxptys(int, int); /* defined in kern/tty_pty.c */ 1864 1865 /* 1866 * Validate parameters and get old / set new parameters 1867 * for pty sysctl function. 1868 */ 1869 static int 1870 sysctl_pty(void *oldp, size_t *oldlenp, void *newp, size_t newlen) 1871 { 1872 int error = 0; 1873 int oldmax = 0, newmax = 0; 1874 1875 /* get current value of maxptys */ 1876 oldmax = pty_maxptys(0, 0); 1877 1878 SYSCTL_SCALAR_CORE_TYP(oldp, oldlenp, &oldmax, int) 1879 1880 if (!error && newp) { 1881 SYSCTL_SCALAR_NEWPCHECK_TYP(newp, newlen, int) 1882 SYSCTL_SCALAR_NEWPCOP_TYP(newp, &newmax, int) 1883 1884 if (newmax != pty_maxptys(newmax, (newp != NULL))) 1885 return (EINVAL); 1886 1887 } 1888 1889 return (error); 1890 } 1891 #endif /* NPTY > 0 */ 1892 1893 static int 1894 sysctl_dotkstat(name, namelen, where, sizep, newp) 1895 int *name; 1896 u_int namelen; 1897 void *where; 1898 size_t *sizep; 1899 void *newp; 1900 { 1901 /* all sysctl names at this level are terminal */ 1902 if (namelen != 1) 1903 return (ENOTDIR); /* overloaded */ 1904 1905 switch (name[0]) { 1906 case KERN_TKSTAT_NIN: 1907 return (sysctl_rdquad(where, sizep, newp, tk_nin)); 1908 case KERN_TKSTAT_NOUT: 1909 return (sysctl_rdquad(where, sizep, newp, tk_nout)); 1910 case KERN_TKSTAT_CANCC: 1911 return (sysctl_rdquad(where, sizep, newp, tk_cancc)); 1912 case KERN_TKSTAT_RAWCC: 1913 return (sysctl_rdquad(where, sizep, newp, tk_rawcc)); 1914 default: 1915 return (EOPNOTSUPP); 1916 } 1917 } 1918