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