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