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