1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved. 24 * Copyright (c) 2018, Joyent, Inc. 25 * Copyright (c) 2017 by Delphix. All rights reserved. 26 * Copyright 2020 OmniOS Community Edition (OmniOSce) Association. 27 */ 28 29 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 30 /* All Rights Reserved */ 31 32 #include <sys/types.h> 33 #include <sys/param.h> 34 #include <sys/time.h> 35 #include <sys/cred.h> 36 #include <sys/policy.h> 37 #include <sys/debug.h> 38 #include <sys/dirent.h> 39 #include <sys/errno.h> 40 #include <sys/file.h> 41 #include <sys/inline.h> 42 #include <sys/kmem.h> 43 #include <sys/pathname.h> 44 #include <sys/proc.h> 45 #include <sys/brand.h> 46 #include <sys/signal.h> 47 #include <sys/stat.h> 48 #include <sys/sysmacros.h> 49 #include <sys/systm.h> 50 #include <sys/zone.h> 51 #include <sys/uio.h> 52 #include <sys/var.h> 53 #include <sys/mode.h> 54 #include <sys/poll.h> 55 #include <sys/user.h> 56 #include <sys/vfs.h> 57 #include <sys/vfs_opreg.h> 58 #include <sys/gfs.h> 59 #include <sys/vnode.h> 60 #include <sys/fault.h> 61 #include <sys/syscall.h> 62 #include <sys/procfs.h> 63 #include <sys/atomic.h> 64 #include <sys/cmn_err.h> 65 #include <sys/contract_impl.h> 66 #include <sys/ctfs.h> 67 #include <sys/avl.h> 68 #include <sys/ctype.h> 69 #include <fs/fs_subr.h> 70 #include <vm/rm.h> 71 #include <vm/as.h> 72 #include <vm/seg.h> 73 #include <vm/seg_vn.h> 74 #include <vm/hat.h> 75 #include <fs/proc/prdata.h> 76 #if defined(__sparc) 77 #include <sys/regset.h> 78 #endif 79 #if defined(__x86) 80 #include <sys/sysi86.h> 81 #endif 82 83 /* 84 * Created by prinit. 85 */ 86 vnodeops_t *prvnodeops; 87 88 /* 89 * Directory characteristics (patterned after the s5 file system). 90 */ 91 #define PRROOTINO 2 92 93 #define PRDIRSIZE 14 94 struct prdirect { 95 ushort_t d_ino; 96 char d_name[PRDIRSIZE]; 97 }; 98 99 #define PRSDSIZE (sizeof (struct prdirect)) 100 101 /* 102 * Directory characteristics. 103 */ 104 typedef struct prdirent { 105 ino64_t d_ino; /* "inode number" of entry */ 106 off64_t d_off; /* offset of disk directory entry */ 107 unsigned short d_reclen; /* length of this record */ 108 char d_name[14]; /* name of file */ 109 } prdirent_t; 110 111 /* 112 * Contents of a /proc/<pid> directory. 113 * Reuse d_ino field for the /proc file type. 114 */ 115 static prdirent_t piddir[] = { 116 { PR_PIDDIR, 1 * sizeof (prdirent_t), sizeof (prdirent_t), 117 "." }, 118 { PR_PROCDIR, 2 * sizeof (prdirent_t), sizeof (prdirent_t), 119 ".." }, 120 { PR_AS, 3 * sizeof (prdirent_t), sizeof (prdirent_t), 121 "as" }, 122 { PR_CTL, 4 * sizeof (prdirent_t), sizeof (prdirent_t), 123 "ctl" }, 124 { PR_STATUS, 5 * sizeof (prdirent_t), sizeof (prdirent_t), 125 "status" }, 126 { PR_LSTATUS, 6 * sizeof (prdirent_t), sizeof (prdirent_t), 127 "lstatus" }, 128 { PR_PSINFO, 7 * sizeof (prdirent_t), sizeof (prdirent_t), 129 "psinfo" }, 130 { PR_LPSINFO, 8 * sizeof (prdirent_t), sizeof (prdirent_t), 131 "lpsinfo" }, 132 { PR_MAP, 9 * sizeof (prdirent_t), sizeof (prdirent_t), 133 "map" }, 134 { PR_RMAP, 10 * sizeof (prdirent_t), sizeof (prdirent_t), 135 "rmap" }, 136 { PR_XMAP, 11 * sizeof (prdirent_t), sizeof (prdirent_t), 137 "xmap" }, 138 { PR_CRED, 12 * sizeof (prdirent_t), sizeof (prdirent_t), 139 "cred" }, 140 { PR_SIGACT, 13 * sizeof (prdirent_t), sizeof (prdirent_t), 141 "sigact" }, 142 { PR_AUXV, 14 * sizeof (prdirent_t), sizeof (prdirent_t), 143 "auxv" }, 144 { PR_USAGE, 15 * sizeof (prdirent_t), sizeof (prdirent_t), 145 "usage" }, 146 { PR_LUSAGE, 16 * sizeof (prdirent_t), sizeof (prdirent_t), 147 "lusage" }, 148 { PR_PAGEDATA, 17 * sizeof (prdirent_t), sizeof (prdirent_t), 149 "pagedata" }, 150 { PR_WATCH, 18 * sizeof (prdirent_t), sizeof (prdirent_t), 151 "watch" }, 152 { PR_CURDIR, 19 * sizeof (prdirent_t), sizeof (prdirent_t), 153 "cwd" }, 154 { PR_ROOTDIR, 20 * sizeof (prdirent_t), sizeof (prdirent_t), 155 "root" }, 156 { PR_FDDIR, 21 * sizeof (prdirent_t), sizeof (prdirent_t), 157 "fd" }, 158 { PR_FDINFODIR, 22 * sizeof (prdirent_t), sizeof (prdirent_t), 159 "fdinfo" }, 160 { PR_OBJECTDIR, 23 * sizeof (prdirent_t), sizeof (prdirent_t), 161 "object" }, 162 { PR_LWPDIR, 24 * sizeof (prdirent_t), sizeof (prdirent_t), 163 "lwp" }, 164 { PR_PRIV, 25 * sizeof (prdirent_t), sizeof (prdirent_t), 165 "priv" }, 166 { PR_PATHDIR, 26 * sizeof (prdirent_t), sizeof (prdirent_t), 167 "path" }, 168 { PR_CTDIR, 27 * sizeof (prdirent_t), sizeof (prdirent_t), 169 "contracts" }, 170 { PR_SECFLAGS, 28 * sizeof (prdirent_t), sizeof (prdirent_t), 171 "secflags" }, 172 #if defined(__x86) 173 { PR_LDT, 29 * sizeof (prdirent_t), sizeof (prdirent_t), 174 "ldt" }, 175 #endif 176 }; 177 178 #define NPIDDIRFILES (sizeof (piddir) / sizeof (piddir[0]) - 2) 179 180 /* 181 * Contents of a /proc/<pid>/lwp/<lwpid> directory. 182 */ 183 static prdirent_t lwpiddir[] = { 184 { PR_LWPIDDIR, 1 * sizeof (prdirent_t), sizeof (prdirent_t), 185 "." }, 186 { PR_LWPDIR, 2 * sizeof (prdirent_t), sizeof (prdirent_t), 187 ".." }, 188 { PR_LWPCTL, 3 * sizeof (prdirent_t), sizeof (prdirent_t), 189 "lwpctl" }, 190 { PR_LWPNAME, 4 * sizeof (prdirent_t), sizeof (prdirent_t), 191 "lwpname" }, 192 { PR_LWPSTATUS, 5 * sizeof (prdirent_t), sizeof (prdirent_t), 193 "lwpstatus" }, 194 { PR_LWPSINFO, 6 * sizeof (prdirent_t), sizeof (prdirent_t), 195 "lwpsinfo" }, 196 { PR_LWPUSAGE, 7 * sizeof (prdirent_t), sizeof (prdirent_t), 197 "lwpusage" }, 198 { PR_XREGS, 8 * sizeof (prdirent_t), sizeof (prdirent_t), 199 "xregs" }, 200 { PR_TMPLDIR, 9 * sizeof (prdirent_t), sizeof (prdirent_t), 201 "templates" }, 202 { PR_SPYMASTER, 10 * sizeof (prdirent_t), sizeof (prdirent_t), 203 "spymaster" }, 204 #if defined(__sparc) 205 { PR_GWINDOWS, 11 * sizeof (prdirent_t), sizeof (prdirent_t), 206 "gwindows" }, 207 { PR_ASRS, 12 * sizeof (prdirent_t), sizeof (prdirent_t), 208 "asrs" }, 209 #endif 210 }; 211 212 #define NLWPIDDIRFILES (sizeof (lwpiddir) / sizeof (lwpiddir[0]) - 2) 213 214 /* 215 * Span of entries in the array files (lstatus, lpsinfo, lusage). 216 * We make the span larger than the size of the structure on purpose, 217 * to make sure that programs cannot use the structure size by mistake. 218 * Align _ILP32 structures at 8 bytes, _LP64 structures at 16 bytes. 219 */ 220 #ifdef _LP64 221 #define LSPAN(type) (round16(sizeof (type)) + 16) 222 #define LSPAN32(type) (round8(sizeof (type)) + 8) 223 #else 224 #define LSPAN(type) (round8(sizeof (type)) + 8) 225 #endif 226 227 static void rebuild_objdir(struct as *); 228 static void prfreecommon(prcommon_t *); 229 static int praccess(vnode_t *, int, int, cred_t *, caller_context_t *); 230 231 static int 232 propen(vnode_t **vpp, int flag, cred_t *cr, caller_context_t *ct) 233 { 234 vnode_t *vp = *vpp; 235 prnode_t *pnp = VTOP(vp); 236 prcommon_t *pcp = pnp->pr_pcommon; 237 prnodetype_t type = pnp->pr_type; 238 vnode_t *rvp; 239 vtype_t vtype; 240 proc_t *p; 241 int error = 0; 242 prnode_t *npnp = NULL; 243 244 /* 245 * Nothing to do for the /proc directory itself. 246 */ 247 if (type == PR_PROCDIR) 248 return (0); 249 250 /* 251 * If we are opening an underlying mapped object, reject opens 252 * for writing regardless of the objects's access modes. 253 * If we are opening a file in the /proc/pid/fd directory, 254 * reject the open for any but a regular file or directory. 255 * Just do it if we are opening the current or root directory. 256 */ 257 switch (type) { 258 case PR_OBJECT: 259 case PR_FD: 260 case PR_CURDIR: 261 case PR_ROOTDIR: 262 rvp = pnp->pr_realvp; 263 vtype = rvp->v_type; 264 if ((type == PR_OBJECT && (flag & FWRITE)) || 265 (type == PR_FD && vtype != VREG && vtype != VDIR)) 266 error = EACCES; 267 else { 268 /* 269 * Need to hold rvp since VOP_OPEN() may release it. 270 */ 271 VN_HOLD(rvp); 272 error = VOP_OPEN(&rvp, flag, cr, ct); 273 if (error) { 274 VN_RELE(rvp); 275 } else { 276 *vpp = rvp; 277 VN_RELE(vp); 278 } 279 } 280 return (error); 281 default: 282 break; 283 } 284 285 /* 286 * If we are opening the pagedata file, allocate a prnode now 287 * to avoid calling kmem_alloc() while holding p->p_lock. 288 */ 289 if (type == PR_PAGEDATA || type == PR_OPAGEDATA) 290 npnp = prgetnode(vp, type); 291 292 /* 293 * If the process exists, lock it now. 294 * Otherwise we have a race condition with prclose(). 295 */ 296 p = pr_p_lock(pnp); 297 mutex_exit(&pr_pidlock); 298 if (p == NULL) { 299 if (npnp != NULL) 300 prfreenode(npnp); 301 return (ENOENT); 302 } 303 ASSERT(p == pcp->prc_proc); 304 ASSERT(p->p_proc_flag & P_PR_LOCK); 305 306 /* 307 * Maintain a count of opens for write. Allow exactly one 308 * O_WRITE|O_EXCL request and fail subsequent ones. 309 * Don't fail opens of old (bletch!) /proc lwp files. 310 * Special case for open by the process itself: 311 * Always allow the open by self and discount this 312 * open for other opens for writing. 313 */ 314 if (flag & FWRITE) { 315 if (p == curproc) { 316 pcp->prc_selfopens++; 317 pnp->pr_flags |= PR_ISSELF; 318 } else if (type == PR_LWPIDFILE) { 319 /* EMPTY */; 320 } else if (flag & FEXCL) { 321 if (pcp->prc_writers > pcp->prc_selfopens) { 322 error = EBUSY; 323 goto out; 324 } 325 /* semantic for old /proc interface */ 326 if (type == PR_PIDDIR) 327 pcp->prc_flags |= PRC_EXCL; 328 } else if (pcp->prc_flags & PRC_EXCL) { 329 ASSERT(pcp->prc_writers > pcp->prc_selfopens); 330 error = secpolicy_proc_excl_open(cr); 331 if (error) 332 goto out; 333 } 334 pcp->prc_writers++; 335 /* 336 * The vnode may have become invalid between the 337 * VOP_LOOKUP() of the /proc vnode and the VOP_OPEN(). 338 * If so, do now what prinvalidate() should have done. 339 */ 340 if ((pnp->pr_flags & PR_INVAL) || 341 (type == PR_PIDDIR && 342 (VTOP(pnp->pr_pidfile)->pr_flags & PR_INVAL))) { 343 if (p != curproc) 344 pcp->prc_selfopens++; 345 ASSERT(pcp->prc_selfopens <= pcp->prc_writers); 346 if (pcp->prc_selfopens == pcp->prc_writers) 347 pcp->prc_flags &= ~PRC_EXCL; 348 } 349 } 350 351 /* 352 * If this is a large file open, indicate that in our flags -- some 353 * procfs structures are not off_t-neutral (e.g., priovec_t), and 354 * the open will need to be differentiated where 32-bit processes 355 * pass these structures across the user/kernel boundary. 356 */ 357 if (flag & FOFFMAX) 358 pnp->pr_flags |= PR_OFFMAX; 359 360 /* 361 * Do file-specific things. 362 */ 363 switch (type) { 364 default: 365 break; 366 case PR_PAGEDATA: 367 case PR_OPAGEDATA: 368 /* 369 * Enable data collection for page data file; 370 * get unique id from the hat layer. 371 */ 372 { 373 int id; 374 375 /* 376 * Drop p->p_lock to call hat_startstat() 377 */ 378 mutex_exit(&p->p_lock); 379 if ((p->p_flag & SSYS) || p->p_as == &kas || 380 (id = hat_startstat(p->p_as)) == -1) { 381 mutex_enter(&p->p_lock); 382 error = ENOMEM; 383 } else if (pnp->pr_hatid == 0) { 384 mutex_enter(&p->p_lock); 385 pnp->pr_hatid = (uint_t)id; 386 } else { 387 mutex_enter(&p->p_lock); 388 /* 389 * Use our newly allocated prnode. 390 */ 391 npnp->pr_hatid = (uint_t)id; 392 /* 393 * prgetnode() initialized most of the prnode. 394 * Duplicate the remainder. 395 */ 396 npnp->pr_ino = pnp->pr_ino; 397 npnp->pr_common = pnp->pr_common; 398 npnp->pr_pcommon = pnp->pr_pcommon; 399 npnp->pr_parent = pnp->pr_parent; 400 VN_HOLD(npnp->pr_parent); 401 npnp->pr_index = pnp->pr_index; 402 403 npnp->pr_next = p->p_plist; 404 p->p_plist = PTOV(npnp); 405 406 VN_RELE(PTOV(pnp)); 407 pnp = npnp; 408 npnp = NULL; 409 *vpp = PTOV(pnp); 410 } 411 } 412 break; 413 } 414 415 out: 416 prunlock(pnp); 417 418 if (npnp != NULL) 419 prfreenode(npnp); 420 return (error); 421 } 422 423 /* ARGSUSED */ 424 static int 425 prclose(vnode_t *vp, int flag, int count, offset_t offset, cred_t *cr, 426 caller_context_t *ct) 427 { 428 prnode_t *pnp = VTOP(vp); 429 prcommon_t *pcp = pnp->pr_pcommon; 430 prnodetype_t type = pnp->pr_type; 431 proc_t *p; 432 kthread_t *t; 433 user_t *up; 434 435 /* 436 * Nothing to do for the /proc directory itself. 437 */ 438 if (type == PR_PROCDIR) 439 return (0); 440 441 ASSERT(type != PR_OBJECT && type != PR_FD && 442 type != PR_CURDIR && type != PR_ROOTDIR); 443 444 /* 445 * If the process exists, lock it now. 446 * Otherwise we have a race condition with propen(). 447 * Hold pr_pidlock across the reference to prc_selfopens, 448 * and prc_writers in case there is no process anymore, 449 * to cover the case of concurrent calls to prclose() 450 * after the process has been reaped by freeproc(). 451 */ 452 p = pr_p_lock(pnp); 453 454 /* 455 * There is nothing more to do until the last close of 456 * the file table entry except to clear the pr_owner 457 * field of the prnode and notify any waiters 458 * (their file descriptor may have just been closed). 459 */ 460 if (count > 1) { 461 mutex_exit(&pr_pidlock); 462 if (pnp->pr_owner == curproc && !fisopen(vp)) 463 pnp->pr_owner = NULL; 464 if (p != NULL) { 465 prnotify(vp); 466 prunlock(pnp); 467 } 468 return (0); 469 } 470 471 /* 472 * Decrement the count of self-opens for writing. 473 * Decrement the total count of opens for writing. 474 * Cancel exclusive opens when only self-opens remain. 475 */ 476 if (flag & FWRITE) { 477 /* 478 * prc_selfopens also contains the count of 479 * invalid writers. See prinvalidate(). 480 */ 481 if ((pnp->pr_flags & (PR_ISSELF|PR_INVAL)) || 482 (type == PR_PIDDIR && 483 (VTOP(pnp->pr_pidfile)->pr_flags & PR_INVAL))) { 484 ASSERT(pcp->prc_selfopens != 0); 485 --pcp->prc_selfopens; 486 } 487 ASSERT(pcp->prc_writers != 0); 488 if (--pcp->prc_writers == pcp->prc_selfopens) 489 pcp->prc_flags &= ~PRC_EXCL; 490 } 491 ASSERT(pcp->prc_writers >= pcp->prc_selfopens); 492 mutex_exit(&pr_pidlock); 493 if (pnp->pr_owner == curproc && !fisopen(vp)) 494 pnp->pr_owner = NULL; 495 496 /* 497 * If there is no process, there is nothing more to do. 498 */ 499 if (p == NULL) 500 return (0); 501 502 ASSERT(p == pcp->prc_proc); 503 prnotify(vp); /* notify waiters */ 504 505 /* 506 * Do file-specific things. 507 */ 508 switch (type) { 509 default: 510 break; 511 case PR_PAGEDATA: 512 case PR_OPAGEDATA: 513 /* 514 * This is a page data file. 515 * Free the hat level statistics. 516 * Drop p->p_lock before calling hat_freestat(). 517 */ 518 mutex_exit(&p->p_lock); 519 if (p->p_as != &kas && pnp->pr_hatid != 0) 520 hat_freestat(p->p_as, pnp->pr_hatid); 521 mutex_enter(&p->p_lock); 522 pnp->pr_hatid = 0; 523 break; 524 } 525 526 /* 527 * On last close of all writable file descriptors, 528 * perform run-on-last-close and/or kill-on-last-close logic. 529 * Can't do this is the /proc agent lwp still exists. 530 */ 531 if (pcp->prc_writers == 0 && 532 p->p_agenttp == NULL && 533 !(pcp->prc_flags & PRC_DESTROY) && 534 p->p_stat != SZOMB && 535 (p->p_proc_flag & (P_PR_RUNLCL|P_PR_KILLCL))) { 536 int killproc; 537 538 /* 539 * Cancel any watchpoints currently in effect. 540 * The process might disappear during this operation. 541 */ 542 if (pr_cancel_watch(pnp) == NULL) 543 return (0); 544 /* 545 * If any tracing flags are set, clear them. 546 */ 547 if (p->p_proc_flag & P_PR_TRACE) { 548 up = PTOU(p); 549 premptyset(&up->u_entrymask); 550 premptyset(&up->u_exitmask); 551 up->u_systrap = 0; 552 } 553 premptyset(&p->p_sigmask); 554 premptyset(&p->p_fltmask); 555 killproc = (p->p_proc_flag & P_PR_KILLCL); 556 p->p_proc_flag &= ~(P_PR_RUNLCL|P_PR_KILLCL|P_PR_TRACE); 557 /* 558 * Cancel any outstanding single-step requests. 559 */ 560 if ((t = p->p_tlist) != NULL) { 561 /* 562 * Drop p_lock because prnostep() touches the stack. 563 * The loop is safe because the process is P_PR_LOCK'd. 564 */ 565 mutex_exit(&p->p_lock); 566 do { 567 prnostep(ttolwp(t)); 568 } while ((t = t->t_forw) != p->p_tlist); 569 mutex_enter(&p->p_lock); 570 } 571 /* 572 * Set runnable all lwps stopped by /proc. 573 */ 574 if (killproc) 575 sigtoproc(p, NULL, SIGKILL); 576 else 577 allsetrun(p); 578 } 579 580 prunlock(pnp); 581 return (0); 582 } 583 584 /* 585 * Array of read functions, indexed by /proc file type. 586 */ 587 static int pr_read_inval(), pr_read_as(), pr_read_status(), 588 pr_read_lstatus(), pr_read_psinfo(), pr_read_lpsinfo(), 589 pr_read_map(), pr_read_rmap(), pr_read_xmap(), 590 pr_read_cred(), pr_read_sigact(), pr_read_auxv(), 591 #if defined(__x86) 592 pr_read_ldt(), 593 #endif 594 pr_read_usage(), pr_read_lusage(), pr_read_pagedata(), 595 pr_read_watch(), pr_read_lwpstatus(), pr_read_lwpsinfo(), 596 pr_read_lwpusage(), pr_read_lwpname(), 597 pr_read_xregs(), pr_read_priv(), 598 pr_read_spymaster(), pr_read_secflags(), 599 #if defined(__sparc) 600 pr_read_gwindows(), pr_read_asrs(), 601 #endif 602 pr_read_piddir(), pr_read_pidfile(), pr_read_opagedata(), 603 pr_read_fdinfo(); 604 605 static int (*pr_read_function[PR_NFILES])() = { 606 pr_read_inval, /* /proc */ 607 pr_read_inval, /* /proc/self */ 608 pr_read_piddir, /* /proc/<pid> (old /proc read()) */ 609 pr_read_as, /* /proc/<pid>/as */ 610 pr_read_inval, /* /proc/<pid>/ctl */ 611 pr_read_status, /* /proc/<pid>/status */ 612 pr_read_lstatus, /* /proc/<pid>/lstatus */ 613 pr_read_psinfo, /* /proc/<pid>/psinfo */ 614 pr_read_lpsinfo, /* /proc/<pid>/lpsinfo */ 615 pr_read_map, /* /proc/<pid>/map */ 616 pr_read_rmap, /* /proc/<pid>/rmap */ 617 pr_read_xmap, /* /proc/<pid>/xmap */ 618 pr_read_cred, /* /proc/<pid>/cred */ 619 pr_read_sigact, /* /proc/<pid>/sigact */ 620 pr_read_auxv, /* /proc/<pid>/auxv */ 621 #if defined(__x86) 622 pr_read_ldt, /* /proc/<pid>/ldt */ 623 #endif 624 pr_read_usage, /* /proc/<pid>/usage */ 625 pr_read_lusage, /* /proc/<pid>/lusage */ 626 pr_read_pagedata, /* /proc/<pid>/pagedata */ 627 pr_read_watch, /* /proc/<pid>/watch */ 628 pr_read_inval, /* /proc/<pid>/cwd */ 629 pr_read_inval, /* /proc/<pid>/root */ 630 pr_read_inval, /* /proc/<pid>/fd */ 631 pr_read_inval, /* /proc/<pid>/fd/nn */ 632 pr_read_inval, /* /proc/<pid>/fdinfo */ 633 pr_read_fdinfo, /* /proc/<pid>/fdinfo/nn */ 634 pr_read_inval, /* /proc/<pid>/object */ 635 pr_read_inval, /* /proc/<pid>/object/xxx */ 636 pr_read_inval, /* /proc/<pid>/lwp */ 637 pr_read_inval, /* /proc/<pid>/lwp/<lwpid> */ 638 pr_read_inval, /* /proc/<pid>/lwp/<lwpid>/lwpctl */ 639 pr_read_lwpname, /* /proc/<pid>/lwp/<lwpid>/lwpname */ 640 pr_read_lwpstatus, /* /proc/<pid>/lwp/<lwpid>/lwpstatus */ 641 pr_read_lwpsinfo, /* /proc/<pid>/lwp/<lwpid>/lwpsinfo */ 642 pr_read_lwpusage, /* /proc/<pid>/lwp/<lwpid>/lwpusage */ 643 pr_read_xregs, /* /proc/<pid>/lwp/<lwpid>/xregs */ 644 pr_read_inval, /* /proc/<pid>/lwp/<lwpid>/templates */ 645 pr_read_inval, /* /proc/<pid>/lwp/<lwpid>/templates/<id> */ 646 pr_read_spymaster, /* /proc/<pid>/lwp/<lwpid>/spymaster */ 647 #if defined(__sparc) 648 pr_read_gwindows, /* /proc/<pid>/lwp/<lwpid>/gwindows */ 649 pr_read_asrs, /* /proc/<pid>/lwp/<lwpid>/asrs */ 650 #endif 651 pr_read_priv, /* /proc/<pid>/priv */ 652 pr_read_inval, /* /proc/<pid>/path */ 653 pr_read_inval, /* /proc/<pid>/path/xxx */ 654 pr_read_inval, /* /proc/<pid>/contracts */ 655 pr_read_inval, /* /proc/<pid>/contracts/<ctid> */ 656 pr_read_secflags, /* /proc/<pid>/secflags */ 657 pr_read_pidfile, /* old process file */ 658 pr_read_pidfile, /* old lwp file */ 659 pr_read_opagedata, /* old pagedata file */ 660 }; 661 662 /* ARGSUSED */ 663 static int 664 pr_read_inval(prnode_t *pnp, uio_t *uiop, cred_t *cr) 665 { 666 /* 667 * No read() on any /proc directory, use getdents(2) instead. 668 * Cannot read a control file either. 669 * An underlying mapped object file cannot get here. 670 */ 671 return (EINVAL); 672 } 673 674 static int 675 pr_uioread(void *base, long count, uio_t *uiop) 676 { 677 int error = 0; 678 679 ASSERT(count >= 0); 680 count -= uiop->uio_offset; 681 if (count > 0 && uiop->uio_offset >= 0) { 682 error = uiomove((char *)base + uiop->uio_offset, 683 count, UIO_READ, uiop); 684 } 685 686 return (error); 687 } 688 689 static int 690 pr_read_as(prnode_t *pnp, uio_t *uiop) 691 { 692 int error; 693 694 ASSERT(pnp->pr_type == PR_AS); 695 696 if ((error = prlock(pnp, ZNO)) == 0) { 697 proc_t *p = pnp->pr_common->prc_proc; 698 struct as *as = p->p_as; 699 700 /* 701 * /proc I/O cannot be done to a system process. 702 * A 32-bit process cannot read a 64-bit process. 703 */ 704 if ((p->p_flag & SSYS) || as == &kas) { 705 error = 0; 706 #ifdef _SYSCALL32_IMPL 707 } else if (curproc->p_model == DATAMODEL_ILP32 && 708 PROCESS_NOT_32BIT(p)) { 709 error = EOVERFLOW; 710 #endif 711 } else { 712 /* 713 * We don't hold p_lock over an i/o operation because 714 * that could lead to deadlock with the clock thread. 715 */ 716 mutex_exit(&p->p_lock); 717 error = prusrio(p, UIO_READ, uiop, 0); 718 mutex_enter(&p->p_lock); 719 } 720 prunlock(pnp); 721 } 722 723 return (error); 724 } 725 726 static int 727 pr_read_status(prnode_t *pnp, uio_t *uiop, cred_t *cr) 728 { 729 pstatus_t *sp; 730 int error; 731 732 ASSERT(pnp->pr_type == PR_STATUS); 733 734 /* 735 * We kmem_alloc() the pstatus structure because 736 * it is so big it might blow the kernel stack. 737 */ 738 sp = kmem_alloc(sizeof (*sp), KM_SLEEP); 739 if ((error = prlock(pnp, ZNO)) == 0) { 740 prgetstatus(pnp->pr_common->prc_proc, sp, VTOZONE(PTOV(pnp))); 741 prunlock(pnp); 742 error = pr_uioread(sp, sizeof (*sp), uiop); 743 } 744 kmem_free(sp, sizeof (*sp)); 745 return (error); 746 } 747 748 static int 749 pr_read_lstatus(prnode_t *pnp, uio_t *uiop, cred_t *cr) 750 { 751 proc_t *p; 752 kthread_t *t; 753 lwpdir_t *ldp; 754 size_t size; 755 prheader_t *php; 756 lwpstatus_t *sp; 757 int error; 758 int nlwp; 759 int i; 760 761 ASSERT(pnp->pr_type == PR_LSTATUS); 762 763 if ((error = prlock(pnp, ZNO)) != 0) 764 return (error); 765 p = pnp->pr_common->prc_proc; 766 nlwp = p->p_lwpcnt; 767 size = sizeof (prheader_t) + nlwp * LSPAN(lwpstatus_t); 768 769 /* drop p->p_lock to do kmem_alloc(KM_SLEEP) */ 770 mutex_exit(&p->p_lock); 771 php = kmem_zalloc(size, KM_SLEEP); 772 mutex_enter(&p->p_lock); 773 /* p->p_lwpcnt can't change while process is locked */ 774 ASSERT(nlwp == p->p_lwpcnt); 775 776 php->pr_nent = nlwp; 777 php->pr_entsize = LSPAN(lwpstatus_t); 778 779 sp = (lwpstatus_t *)(php + 1); 780 for (ldp = p->p_lwpdir, i = 0; i < p->p_lwpdir_sz; i++, ldp++) { 781 if (ldp->ld_entry == NULL || 782 (t = ldp->ld_entry->le_thread) == NULL) 783 continue; 784 prgetlwpstatus(t, sp, VTOZONE(PTOV(pnp))); 785 sp = (lwpstatus_t *)((caddr_t)sp + LSPAN(lwpstatus_t)); 786 } 787 prunlock(pnp); 788 789 error = pr_uioread(php, size, uiop); 790 kmem_free(php, size); 791 return (error); 792 } 793 794 static int 795 pr_read_psinfo(prnode_t *pnp, uio_t *uiop, cred_t *cr) 796 { 797 psinfo_t psinfo; 798 proc_t *p; 799 int error = 0; 800 801 ASSERT(pnp->pr_type == PR_PSINFO); 802 803 /* 804 * We don't want the full treatment of prlock(pnp) here. 805 * This file is world-readable and never goes invalid. 806 * It doesn't matter if we are in the middle of an exec(). 807 */ 808 p = pr_p_lock(pnp); 809 mutex_exit(&pr_pidlock); 810 if (p == NULL) 811 error = ENOENT; 812 else { 813 ASSERT(p == pnp->pr_common->prc_proc); 814 prgetpsinfo(p, &psinfo); 815 prunlock(pnp); 816 error = pr_uioread(&psinfo, sizeof (psinfo), uiop); 817 } 818 return (error); 819 } 820 821 static int 822 pr_read_fdinfo(prnode_t *pnp, uio_t *uiop, cred_t *cr) 823 { 824 prfdinfo_t *fdinfo; 825 list_t data; 826 proc_t *p; 827 vnode_t *vp; 828 uint_t fd; 829 file_t *fp; 830 cred_t *file_cred; 831 short ufp_flag; 832 int error = 0; 833 834 ASSERT(pnp->pr_type == PR_FDINFO); 835 836 /* 837 * This is a guess at the size of the structure that needs to 838 * be returned. It's a balance between not allocating too much more 839 * space than is required and not requiring too many subsequent 840 * reallocations. Allocate it before acquiring the process lock. 841 */ 842 pr_iol_initlist(&data, sizeof (prfdinfo_t) + MAXPATHLEN + 2, 1); 843 844 if ((error = prlock(pnp, ZNO)) != 0) { 845 pr_iol_freelist(&data); 846 return (error); 847 } 848 849 p = pnp->pr_common->prc_proc; 850 851 if ((p->p_flag & SSYS) || p->p_as == &kas) { 852 prunlock(pnp); 853 pr_iol_freelist(&data); 854 return (0); 855 } 856 857 fd = pnp->pr_index; 858 859 /* Fetch and lock the file_t for this descriptor */ 860 fp = pr_getf(p, fd, &ufp_flag); 861 862 if (fp == NULL) { 863 error = ENOENT; 864 prunlock(pnp); 865 goto out; 866 } 867 868 vp = fp->f_vnode; 869 VN_HOLD(vp); 870 871 /* 872 * For fdinfo, we don't want to include the placeholder pr_misc at the 873 * end of the struct. We'll terminate the data with an empty pr_misc 874 * header before returning. 875 */ 876 877 fdinfo = pr_iol_newbuf(&data, offsetof(prfdinfo_t, pr_misc)); 878 fdinfo->pr_fd = fd; 879 fdinfo->pr_fdflags = ufp_flag; 880 fdinfo->pr_fileflags = fp->f_flag2 << 16 | fp->f_flag; 881 if ((fdinfo->pr_fileflags & (FSEARCH | FEXEC)) == 0) 882 fdinfo->pr_fileflags += FOPEN; 883 fdinfo->pr_offset = fp->f_offset; 884 file_cred = fp->f_cred; 885 crhold(file_cred); 886 /* 887 * Information from the vnode (rather than the file_t) is retrieved 888 * later, in prgetfdinfo() - for example sock_getfasync() 889 */ 890 pr_releasef(p, fd); 891 892 prunlock(pnp); 893 894 error = prgetfdinfo(p, vp, fdinfo, cr, file_cred, &data); 895 896 crfree(file_cred); 897 898 VN_RELE(vp); 899 900 out: 901 if (error == 0) 902 error = pr_iol_uiomove_and_free(&data, uiop, error); 903 else 904 pr_iol_freelist(&data); 905 906 return (error); 907 } 908 909 static int 910 pr_read_lpsinfo(prnode_t *pnp, uio_t *uiop, cred_t *cr) 911 { 912 proc_t *p; 913 kthread_t *t; 914 lwpdir_t *ldp; 915 lwpent_t *lep; 916 size_t size; 917 prheader_t *php; 918 lwpsinfo_t *sp; 919 int error; 920 int nlwp; 921 int i; 922 923 ASSERT(pnp->pr_type == PR_LPSINFO); 924 925 /* 926 * We don't want the full treatment of prlock(pnp) here. 927 * This file is world-readable and never goes invalid. 928 * It doesn't matter if we are in the middle of an exec(). 929 */ 930 p = pr_p_lock(pnp); 931 mutex_exit(&pr_pidlock); 932 if (p == NULL) 933 return (ENOENT); 934 ASSERT(p == pnp->pr_common->prc_proc); 935 if ((nlwp = p->p_lwpcnt + p->p_zombcnt) == 0) { 936 prunlock(pnp); 937 return (ENOENT); 938 } 939 size = sizeof (prheader_t) + nlwp * LSPAN(lwpsinfo_t); 940 941 /* drop p->p_lock to do kmem_alloc(KM_SLEEP) */ 942 mutex_exit(&p->p_lock); 943 php = kmem_zalloc(size, KM_SLEEP); 944 mutex_enter(&p->p_lock); 945 /* p->p_lwpcnt can't change while process is locked */ 946 ASSERT(nlwp == p->p_lwpcnt + p->p_zombcnt); 947 948 php->pr_nent = nlwp; 949 php->pr_entsize = LSPAN(lwpsinfo_t); 950 951 sp = (lwpsinfo_t *)(php + 1); 952 for (ldp = p->p_lwpdir, i = 0; i < p->p_lwpdir_sz; i++, ldp++) { 953 if ((lep = ldp->ld_entry) == NULL) 954 continue; 955 if ((t = lep->le_thread) != NULL) 956 prgetlwpsinfo(t, sp); 957 else { 958 bzero(sp, sizeof (*sp)); 959 sp->pr_lwpid = lep->le_lwpid; 960 sp->pr_state = SZOMB; 961 sp->pr_sname = 'Z'; 962 sp->pr_start.tv_sec = lep->le_start; 963 sp->pr_bindpro = PBIND_NONE; 964 sp->pr_bindpset = PS_NONE; 965 } 966 sp = (lwpsinfo_t *)((caddr_t)sp + LSPAN(lwpsinfo_t)); 967 } 968 prunlock(pnp); 969 970 error = pr_uioread(php, size, uiop); 971 kmem_free(php, size); 972 return (error); 973 } 974 975 static int 976 pr_read_map_common(prnode_t *pnp, uio_t *uiop, prnodetype_t type) 977 { 978 proc_t *p; 979 struct as *as; 980 list_t iolhead; 981 int error; 982 983 readmap_common: 984 if ((error = prlock(pnp, ZNO)) != 0) 985 return (error); 986 987 p = pnp->pr_common->prc_proc; 988 as = p->p_as; 989 990 if ((p->p_flag & SSYS) || as == &kas) { 991 prunlock(pnp); 992 return (0); 993 } 994 995 if (!AS_LOCK_TRYENTER(as, RW_WRITER)) { 996 prunlock(pnp); 997 delay(1); 998 goto readmap_common; 999 } 1000 mutex_exit(&p->p_lock); 1001 1002 switch (type) { 1003 case PR_XMAP: 1004 error = prgetxmap(p, &iolhead); 1005 break; 1006 case PR_RMAP: 1007 error = prgetmap(p, 1, &iolhead); 1008 break; 1009 case PR_MAP: 1010 error = prgetmap(p, 0, &iolhead); 1011 break; 1012 } 1013 1014 AS_LOCK_EXIT(as); 1015 mutex_enter(&p->p_lock); 1016 prunlock(pnp); 1017 1018 error = pr_iol_uiomove_and_free(&iolhead, uiop, error); 1019 1020 return (error); 1021 } 1022 1023 static int 1024 pr_read_map(prnode_t *pnp, uio_t *uiop, cred_t *cr) 1025 { 1026 ASSERT(pnp->pr_type == PR_MAP); 1027 return (pr_read_map_common(pnp, uiop, pnp->pr_type)); 1028 } 1029 1030 static int 1031 pr_read_rmap(prnode_t *pnp, uio_t *uiop, cred_t *cr) 1032 { 1033 ASSERT(pnp->pr_type == PR_RMAP); 1034 return (pr_read_map_common(pnp, uiop, pnp->pr_type)); 1035 } 1036 1037 static int 1038 pr_read_xmap(prnode_t *pnp, uio_t *uiop, cred_t *cr) 1039 { 1040 ASSERT(pnp->pr_type == PR_XMAP); 1041 return (pr_read_map_common(pnp, uiop, pnp->pr_type)); 1042 } 1043 1044 static int 1045 pr_read_cred(prnode_t *pnp, uio_t *uiop, cred_t *cr) 1046 { 1047 proc_t *p; 1048 prcred_t *pcrp; 1049 int error; 1050 size_t count; 1051 1052 ASSERT(pnp->pr_type == PR_CRED); 1053 1054 /* 1055 * We kmem_alloc() the prcred_t structure because 1056 * the number of supplementary groups is variable. 1057 */ 1058 pcrp = 1059 kmem_alloc(sizeof (prcred_t) + sizeof (gid_t) * (ngroups_max - 1), 1060 KM_SLEEP); 1061 1062 if ((error = prlock(pnp, ZNO)) != 0) 1063 goto out; 1064 p = pnp->pr_common->prc_proc; 1065 ASSERT(p != NULL); 1066 1067 prgetcred(p, pcrp); 1068 prunlock(pnp); 1069 1070 count = sizeof (prcred_t); 1071 if (pcrp->pr_ngroups > 1) 1072 count += sizeof (gid_t) * (pcrp->pr_ngroups - 1); 1073 error = pr_uioread(pcrp, count, uiop); 1074 out: 1075 kmem_free(pcrp, sizeof (prcred_t) + sizeof (gid_t) * (ngroups_max - 1)); 1076 return (error); 1077 } 1078 1079 static int 1080 pr_read_priv(prnode_t *pnp, uio_t *uiop, cred_t *cr) 1081 { 1082 proc_t *p; 1083 size_t psize = prgetprivsize(); 1084 prpriv_t *ppriv = kmem_alloc(psize, KM_SLEEP); 1085 int error; 1086 1087 ASSERT(pnp->pr_type == PR_PRIV); 1088 1089 if ((error = prlock(pnp, ZNO)) != 0) 1090 goto out; 1091 p = pnp->pr_common->prc_proc; 1092 ASSERT(p != NULL); 1093 1094 prgetpriv(p, ppriv); 1095 prunlock(pnp); 1096 1097 error = pr_uioread(ppriv, psize, uiop); 1098 out: 1099 kmem_free(ppriv, psize); 1100 return (error); 1101 } 1102 1103 static int 1104 pr_read_sigact(prnode_t *pnp, uio_t *uiop, cred_t *cr) 1105 { 1106 int nsig = PROC_IS_BRANDED(curproc)? BROP(curproc)->b_nsig : NSIG; 1107 proc_t *p; 1108 struct sigaction *sap; 1109 int sig; 1110 int error; 1111 user_t *up; 1112 1113 ASSERT(pnp->pr_type == PR_SIGACT); 1114 1115 /* 1116 * We kmem_alloc() the sigaction array because 1117 * it is so big it might blow the kernel stack. 1118 */ 1119 sap = kmem_alloc((nsig-1) * sizeof (struct sigaction), KM_SLEEP); 1120 1121 if ((error = prlock(pnp, ZNO)) != 0) 1122 goto out; 1123 p = pnp->pr_common->prc_proc; 1124 ASSERT(p != NULL); 1125 1126 if (uiop->uio_offset >= (nsig-1)*sizeof (struct sigaction)) { 1127 prunlock(pnp); 1128 goto out; 1129 } 1130 1131 up = PTOU(p); 1132 for (sig = 1; sig < nsig; sig++) 1133 prgetaction(p, up, sig, &sap[sig-1]); 1134 prunlock(pnp); 1135 1136 error = pr_uioread(sap, (nsig - 1) * sizeof (struct sigaction), uiop); 1137 out: 1138 kmem_free(sap, (nsig-1) * sizeof (struct sigaction)); 1139 return (error); 1140 } 1141 1142 static int 1143 pr_read_auxv(prnode_t *pnp, uio_t *uiop, cred_t *cr) 1144 { 1145 auxv_t auxv[__KERN_NAUXV_IMPL]; 1146 proc_t *p; 1147 user_t *up; 1148 int error; 1149 1150 ASSERT(pnp->pr_type == PR_AUXV); 1151 1152 if ((error = prlock(pnp, ZNO)) != 0) 1153 return (error); 1154 1155 if (uiop->uio_offset >= sizeof (auxv)) { 1156 prunlock(pnp); 1157 return (0); 1158 } 1159 1160 p = pnp->pr_common->prc_proc; 1161 up = PTOU(p); 1162 bcopy(up->u_auxv, auxv, sizeof (auxv)); 1163 prunlock(pnp); 1164 1165 return (pr_uioread(auxv, sizeof (auxv), uiop)); 1166 } 1167 1168 #if defined(__x86) 1169 /* 1170 * XX64 1171 * This is almost certainly broken for the amd64 kernel, because 1172 * we have two kinds of LDT structures to export -- one for compatibility 1173 * mode, and one for long mode, sigh. 1174 * 1175 * For now let's just have a ldt of size 0 for 64-bit processes. 1176 */ 1177 static int 1178 pr_read_ldt(prnode_t *pnp, uio_t *uiop, cred_t *cr) 1179 { 1180 proc_t *p; 1181 struct ssd *ssd; 1182 size_t size; 1183 int error; 1184 1185 ASSERT(pnp->pr_type == PR_LDT); 1186 1187 if ((error = prlock(pnp, ZNO)) != 0) 1188 return (error); 1189 p = pnp->pr_common->prc_proc; 1190 1191 mutex_exit(&p->p_lock); 1192 mutex_enter(&p->p_ldtlock); 1193 size = prnldt(p) * sizeof (struct ssd); 1194 if (uiop->uio_offset >= size) { 1195 mutex_exit(&p->p_ldtlock); 1196 mutex_enter(&p->p_lock); 1197 prunlock(pnp); 1198 return (0); 1199 } 1200 1201 ssd = kmem_alloc(size, KM_SLEEP); 1202 prgetldt(p, ssd); 1203 mutex_exit(&p->p_ldtlock); 1204 mutex_enter(&p->p_lock); 1205 prunlock(pnp); 1206 1207 error = pr_uioread(ssd, size, uiop); 1208 kmem_free(ssd, size); 1209 return (error); 1210 } 1211 #endif /* __x86 */ 1212 1213 static int 1214 pr_read_usage(prnode_t *pnp, uio_t *uiop, cred_t *cr) 1215 { 1216 prhusage_t *pup; 1217 prusage_t *upup; 1218 proc_t *p; 1219 kthread_t *t; 1220 int error; 1221 1222 ASSERT(pnp->pr_type == PR_USAGE); 1223 1224 /* allocate now, before locking the process */ 1225 pup = kmem_zalloc(sizeof (*pup), KM_SLEEP); 1226 upup = kmem_alloc(sizeof (*upup), KM_SLEEP); 1227 1228 /* 1229 * We don't want the full treatment of prlock(pnp) here. 1230 * This file is world-readable and never goes invalid. 1231 * It doesn't matter if we are in the middle of an exec(). 1232 */ 1233 p = pr_p_lock(pnp); 1234 mutex_exit(&pr_pidlock); 1235 if (p == NULL) { 1236 error = ENOENT; 1237 goto out; 1238 } 1239 ASSERT(p == pnp->pr_common->prc_proc); 1240 1241 if (uiop->uio_offset >= sizeof (prusage_t)) { 1242 prunlock(pnp); 1243 error = 0; 1244 goto out; 1245 } 1246 1247 pup->pr_tstamp = gethrtime(); 1248 1249 pup->pr_count = p->p_defunct; 1250 pup->pr_create = p->p_mstart; 1251 pup->pr_term = p->p_mterm; 1252 1253 pup->pr_rtime = p->p_mlreal; 1254 pup->pr_utime = p->p_acct[LMS_USER]; 1255 pup->pr_stime = p->p_acct[LMS_SYSTEM]; 1256 pup->pr_ttime = p->p_acct[LMS_TRAP]; 1257 pup->pr_tftime = p->p_acct[LMS_TFAULT]; 1258 pup->pr_dftime = p->p_acct[LMS_DFAULT]; 1259 pup->pr_kftime = p->p_acct[LMS_KFAULT]; 1260 pup->pr_ltime = p->p_acct[LMS_USER_LOCK]; 1261 pup->pr_slptime = p->p_acct[LMS_SLEEP]; 1262 pup->pr_wtime = p->p_acct[LMS_WAIT_CPU]; 1263 pup->pr_stoptime = p->p_acct[LMS_STOPPED]; 1264 1265 pup->pr_minf = p->p_ru.minflt; 1266 pup->pr_majf = p->p_ru.majflt; 1267 pup->pr_nswap = p->p_ru.nswap; 1268 pup->pr_inblk = p->p_ru.inblock; 1269 pup->pr_oublk = p->p_ru.oublock; 1270 pup->pr_msnd = p->p_ru.msgsnd; 1271 pup->pr_mrcv = p->p_ru.msgrcv; 1272 pup->pr_sigs = p->p_ru.nsignals; 1273 pup->pr_vctx = p->p_ru.nvcsw; 1274 pup->pr_ictx = p->p_ru.nivcsw; 1275 pup->pr_sysc = p->p_ru.sysc; 1276 pup->pr_ioch = p->p_ru.ioch; 1277 1278 /* 1279 * Add the usage information for each active lwp. 1280 */ 1281 if ((t = p->p_tlist) != NULL && 1282 !(pnp->pr_pcommon->prc_flags & PRC_DESTROY)) { 1283 do { 1284 if (t->t_proc_flag & TP_LWPEXIT) 1285 continue; 1286 pup->pr_count++; 1287 praddusage(t, pup); 1288 } while ((t = t->t_forw) != p->p_tlist); 1289 } 1290 1291 prunlock(pnp); 1292 1293 prcvtusage(pup, upup); 1294 1295 error = pr_uioread(upup, sizeof (prusage_t), uiop); 1296 out: 1297 kmem_free(pup, sizeof (*pup)); 1298 kmem_free(upup, sizeof (*upup)); 1299 return (error); 1300 } 1301 1302 static int 1303 pr_read_lusage(prnode_t *pnp, uio_t *uiop, cred_t *cr) 1304 { 1305 int nlwp; 1306 prhusage_t *pup; 1307 prheader_t *php; 1308 prusage_t *upup; 1309 size_t size; 1310 hrtime_t curtime; 1311 proc_t *p; 1312 kthread_t *t; 1313 lwpdir_t *ldp; 1314 int error; 1315 int i; 1316 1317 ASSERT(pnp->pr_type == PR_LUSAGE); 1318 1319 /* 1320 * We don't want the full treatment of prlock(pnp) here. 1321 * This file is world-readable and never goes invalid. 1322 * It doesn't matter if we are in the middle of an exec(). 1323 */ 1324 p = pr_p_lock(pnp); 1325 mutex_exit(&pr_pidlock); 1326 if (p == NULL) 1327 return (ENOENT); 1328 ASSERT(p == pnp->pr_common->prc_proc); 1329 if ((nlwp = p->p_lwpcnt) == 0) { 1330 prunlock(pnp); 1331 return (ENOENT); 1332 } 1333 1334 size = sizeof (prheader_t) + (nlwp + 1) * LSPAN(prusage_t); 1335 if (uiop->uio_offset >= size) { 1336 prunlock(pnp); 1337 return (0); 1338 } 1339 1340 /* drop p->p_lock to do kmem_alloc(KM_SLEEP) */ 1341 mutex_exit(&p->p_lock); 1342 pup = kmem_zalloc(size + sizeof (prhusage_t), KM_SLEEP); 1343 mutex_enter(&p->p_lock); 1344 /* p->p_lwpcnt can't change while process is locked */ 1345 ASSERT(nlwp == p->p_lwpcnt); 1346 1347 php = (prheader_t *)(pup + 1); 1348 upup = (prusage_t *)(php + 1); 1349 1350 php->pr_nent = nlwp + 1; 1351 php->pr_entsize = LSPAN(prusage_t); 1352 1353 curtime = gethrtime(); 1354 1355 /* 1356 * First the summation over defunct lwps. 1357 */ 1358 pup->pr_count = p->p_defunct; 1359 pup->pr_tstamp = curtime; 1360 pup->pr_create = p->p_mstart; 1361 pup->pr_term = p->p_mterm; 1362 1363 pup->pr_rtime = p->p_mlreal; 1364 pup->pr_utime = p->p_acct[LMS_USER]; 1365 pup->pr_stime = p->p_acct[LMS_SYSTEM]; 1366 pup->pr_ttime = p->p_acct[LMS_TRAP]; 1367 pup->pr_tftime = p->p_acct[LMS_TFAULT]; 1368 pup->pr_dftime = p->p_acct[LMS_DFAULT]; 1369 pup->pr_kftime = p->p_acct[LMS_KFAULT]; 1370 pup->pr_ltime = p->p_acct[LMS_USER_LOCK]; 1371 pup->pr_slptime = p->p_acct[LMS_SLEEP]; 1372 pup->pr_wtime = p->p_acct[LMS_WAIT_CPU]; 1373 pup->pr_stoptime = p->p_acct[LMS_STOPPED]; 1374 1375 pup->pr_minf = p->p_ru.minflt; 1376 pup->pr_majf = p->p_ru.majflt; 1377 pup->pr_nswap = p->p_ru.nswap; 1378 pup->pr_inblk = p->p_ru.inblock; 1379 pup->pr_oublk = p->p_ru.oublock; 1380 pup->pr_msnd = p->p_ru.msgsnd; 1381 pup->pr_mrcv = p->p_ru.msgrcv; 1382 pup->pr_sigs = p->p_ru.nsignals; 1383 pup->pr_vctx = p->p_ru.nvcsw; 1384 pup->pr_ictx = p->p_ru.nivcsw; 1385 pup->pr_sysc = p->p_ru.sysc; 1386 pup->pr_ioch = p->p_ru.ioch; 1387 1388 prcvtusage(pup, upup); 1389 1390 /* 1391 * Fill one prusage struct for each active lwp. 1392 */ 1393 for (ldp = p->p_lwpdir, i = 0; i < p->p_lwpdir_sz; i++, ldp++) { 1394 if (ldp->ld_entry == NULL || 1395 (t = ldp->ld_entry->le_thread) == NULL) 1396 continue; 1397 ASSERT(!(t->t_proc_flag & TP_LWPEXIT)); 1398 ASSERT(nlwp > 0); 1399 --nlwp; 1400 upup = (prusage_t *)((caddr_t)upup + LSPAN(prusage_t)); 1401 prgetusage(t, pup); 1402 prcvtusage(pup, upup); 1403 } 1404 ASSERT(nlwp == 0); 1405 1406 prunlock(pnp); 1407 1408 error = pr_uioread(php, size, uiop); 1409 kmem_free(pup, size + sizeof (prhusage_t)); 1410 return (error); 1411 } 1412 1413 static int 1414 pr_read_pagedata(prnode_t *pnp, uio_t *uiop, cred_t *cr) 1415 { 1416 proc_t *p; 1417 int error; 1418 1419 ASSERT(pnp->pr_type == PR_PAGEDATA); 1420 1421 if ((error = prlock(pnp, ZNO)) != 0) 1422 return (error); 1423 1424 p = pnp->pr_common->prc_proc; 1425 if ((p->p_flag & SSYS) || p->p_as == &kas) { 1426 prunlock(pnp); 1427 return (0); 1428 } 1429 1430 mutex_exit(&p->p_lock); 1431 error = prpdread(p, pnp->pr_hatid, uiop); 1432 mutex_enter(&p->p_lock); 1433 1434 prunlock(pnp); 1435 return (error); 1436 } 1437 1438 static int 1439 pr_read_opagedata(prnode_t *pnp, uio_t *uiop, cred_t *cr) 1440 { 1441 proc_t *p; 1442 struct as *as; 1443 int error; 1444 1445 ASSERT(pnp->pr_type == PR_OPAGEDATA); 1446 1447 if ((error = prlock(pnp, ZNO)) != 0) 1448 return (error); 1449 1450 p = pnp->pr_common->prc_proc; 1451 as = p->p_as; 1452 if ((p->p_flag & SSYS) || as == &kas) { 1453 prunlock(pnp); 1454 return (0); 1455 } 1456 1457 mutex_exit(&p->p_lock); 1458 error = oprpdread(as, pnp->pr_hatid, uiop); 1459 mutex_enter(&p->p_lock); 1460 1461 prunlock(pnp); 1462 return (error); 1463 } 1464 1465 static int 1466 pr_read_watch(prnode_t *pnp, uio_t *uiop, cred_t *cr) 1467 { 1468 proc_t *p; 1469 int error; 1470 prwatch_t *Bpwp; 1471 size_t size; 1472 prwatch_t *pwp; 1473 int nwarea; 1474 struct watched_area *pwarea; 1475 1476 ASSERT(pnp->pr_type == PR_WATCH); 1477 1478 if ((error = prlock(pnp, ZNO)) != 0) 1479 return (error); 1480 1481 p = pnp->pr_common->prc_proc; 1482 nwarea = avl_numnodes(&p->p_warea); 1483 size = nwarea * sizeof (prwatch_t); 1484 if (uiop->uio_offset >= size) { 1485 prunlock(pnp); 1486 return (0); 1487 } 1488 1489 /* drop p->p_lock to do kmem_alloc(KM_SLEEP) */ 1490 mutex_exit(&p->p_lock); 1491 Bpwp = pwp = kmem_zalloc(size, KM_SLEEP); 1492 mutex_enter(&p->p_lock); 1493 /* p->p_nwarea can't change while process is locked */ 1494 ASSERT(nwarea == avl_numnodes(&p->p_warea)); 1495 1496 /* gather the watched areas */ 1497 for (pwarea = avl_first(&p->p_warea); pwarea != NULL; 1498 pwarea = AVL_NEXT(&p->p_warea, pwarea), pwp++) { 1499 pwp->pr_vaddr = (uintptr_t)pwarea->wa_vaddr; 1500 pwp->pr_size = pwarea->wa_eaddr - pwarea->wa_vaddr; 1501 pwp->pr_wflags = (int)pwarea->wa_flags; 1502 } 1503 1504 prunlock(pnp); 1505 1506 error = pr_uioread(Bpwp, size, uiop); 1507 kmem_free(Bpwp, size); 1508 return (error); 1509 } 1510 1511 static int 1512 pr_read_lwpstatus(prnode_t *pnp, uio_t *uiop, cred_t *cr) 1513 { 1514 lwpstatus_t *sp; 1515 int error; 1516 1517 ASSERT(pnp->pr_type == PR_LWPSTATUS); 1518 1519 /* 1520 * We kmem_alloc() the lwpstatus structure because 1521 * it is so big it might blow the kernel stack. 1522 */ 1523 sp = kmem_alloc(sizeof (*sp), KM_SLEEP); 1524 1525 if ((error = prlock(pnp, ZNO)) != 0) 1526 goto out; 1527 1528 if (uiop->uio_offset >= sizeof (*sp)) { 1529 prunlock(pnp); 1530 goto out; 1531 } 1532 1533 prgetlwpstatus(pnp->pr_common->prc_thread, sp, VTOZONE(PTOV(pnp))); 1534 prunlock(pnp); 1535 1536 error = pr_uioread(sp, sizeof (*sp), uiop); 1537 out: 1538 kmem_free(sp, sizeof (*sp)); 1539 return (error); 1540 } 1541 1542 static int 1543 pr_read_lwpsinfo(prnode_t *pnp, uio_t *uiop, cred_t *cr) 1544 { 1545 lwpsinfo_t lwpsinfo; 1546 proc_t *p; 1547 kthread_t *t; 1548 lwpent_t *lep; 1549 1550 ASSERT(pnp->pr_type == PR_LWPSINFO); 1551 1552 /* 1553 * We don't want the full treatment of prlock(pnp) here. 1554 * This file is world-readable and never goes invalid. 1555 * It doesn't matter if we are in the middle of an exec(). 1556 */ 1557 p = pr_p_lock(pnp); 1558 mutex_exit(&pr_pidlock); 1559 if (p == NULL) 1560 return (ENOENT); 1561 ASSERT(p == pnp->pr_common->prc_proc); 1562 if (pnp->pr_common->prc_tslot == -1) { 1563 prunlock(pnp); 1564 return (ENOENT); 1565 } 1566 1567 if (uiop->uio_offset >= sizeof (lwpsinfo)) { 1568 prunlock(pnp); 1569 return (0); 1570 } 1571 1572 if ((t = pnp->pr_common->prc_thread) != NULL) 1573 prgetlwpsinfo(t, &lwpsinfo); 1574 else { 1575 lep = p->p_lwpdir[pnp->pr_common->prc_tslot].ld_entry; 1576 bzero(&lwpsinfo, sizeof (lwpsinfo)); 1577 lwpsinfo.pr_lwpid = lep->le_lwpid; 1578 lwpsinfo.pr_state = SZOMB; 1579 lwpsinfo.pr_sname = 'Z'; 1580 lwpsinfo.pr_start.tv_sec = lep->le_start; 1581 lwpsinfo.pr_bindpro = PBIND_NONE; 1582 lwpsinfo.pr_bindpset = PS_NONE; 1583 } 1584 prunlock(pnp); 1585 1586 return (pr_uioread(&lwpsinfo, sizeof (lwpsinfo), uiop)); 1587 } 1588 1589 static int 1590 pr_read_lwpusage(prnode_t *pnp, uio_t *uiop, cred_t *cr) 1591 { 1592 prhusage_t *pup; 1593 prusage_t *upup; 1594 proc_t *p; 1595 int error; 1596 1597 ASSERT(pnp->pr_type == PR_LWPUSAGE); 1598 1599 /* allocate now, before locking the process */ 1600 pup = kmem_zalloc(sizeof (*pup), KM_SLEEP); 1601 upup = kmem_alloc(sizeof (*upup), KM_SLEEP); 1602 1603 /* 1604 * We don't want the full treatment of prlock(pnp) here. 1605 * This file is world-readable and never goes invalid. 1606 * It doesn't matter if we are in the middle of an exec(). 1607 */ 1608 p = pr_p_lock(pnp); 1609 mutex_exit(&pr_pidlock); 1610 if (p == NULL) { 1611 error = ENOENT; 1612 goto out; 1613 } 1614 ASSERT(p == pnp->pr_common->prc_proc); 1615 if (pnp->pr_common->prc_thread == NULL) { 1616 prunlock(pnp); 1617 error = ENOENT; 1618 goto out; 1619 } 1620 if (uiop->uio_offset >= sizeof (prusage_t)) { 1621 prunlock(pnp); 1622 error = 0; 1623 goto out; 1624 } 1625 1626 pup->pr_tstamp = gethrtime(); 1627 prgetusage(pnp->pr_common->prc_thread, pup); 1628 1629 prunlock(pnp); 1630 1631 prcvtusage(pup, upup); 1632 1633 error = pr_uioread(upup, sizeof (prusage_t), uiop); 1634 out: 1635 kmem_free(pup, sizeof (*pup)); 1636 kmem_free(upup, sizeof (*upup)); 1637 return (error); 1638 } 1639 1640 static int 1641 pr_read_lwpname(prnode_t *pnp, uio_t *uiop, cred_t *cr) 1642 { 1643 char lwpname[THREAD_NAME_MAX]; 1644 kthread_t *t; 1645 int error; 1646 1647 ASSERT(pnp->pr_type == PR_LWPNAME); 1648 1649 if (uiop->uio_offset >= THREAD_NAME_MAX) 1650 return (0); 1651 1652 if ((error = prlock(pnp, ZNO)) != 0) 1653 return (error); 1654 1655 bzero(lwpname, sizeof (lwpname)); 1656 1657 t = pnp->pr_common->prc_thread; 1658 1659 if (t->t_name != NULL) 1660 (void) strlcpy(lwpname, t->t_name, sizeof (lwpname)); 1661 1662 prunlock(pnp); 1663 1664 return (pr_uioread(lwpname, sizeof (lwpname), uiop)); 1665 } 1666 1667 /* ARGSUSED */ 1668 static int 1669 pr_read_xregs(prnode_t *pnp, uio_t *uiop, cred_t *cr) 1670 { 1671 #if defined(__sparc) 1672 proc_t *p; 1673 kthread_t *t; 1674 int error; 1675 char *xreg; 1676 size_t size; 1677 1678 ASSERT(pnp->pr_type == PR_XREGS); 1679 1680 xreg = kmem_zalloc(sizeof (prxregset_t), KM_SLEEP); 1681 1682 if ((error = prlock(pnp, ZNO)) != 0) 1683 goto out; 1684 1685 p = pnp->pr_common->prc_proc; 1686 t = pnp->pr_common->prc_thread; 1687 1688 size = prhasx(p)? prgetprxregsize(p) : 0; 1689 if (uiop->uio_offset >= size) { 1690 prunlock(pnp); 1691 goto out; 1692 } 1693 1694 /* drop p->p_lock while (possibly) touching the stack */ 1695 mutex_exit(&p->p_lock); 1696 prgetprxregs(ttolwp(t), xreg); 1697 mutex_enter(&p->p_lock); 1698 prunlock(pnp); 1699 1700 error = pr_uioread(xreg, size, uiop); 1701 out: 1702 kmem_free(xreg, sizeof (prxregset_t)); 1703 return (error); 1704 #else 1705 return (0); 1706 #endif 1707 } 1708 1709 static int 1710 pr_read_spymaster(prnode_t *pnp, uio_t *uiop, cred_t *cr) 1711 { 1712 psinfo_t psinfo; 1713 int error; 1714 klwp_t *lwp; 1715 1716 ASSERT(pnp->pr_type == PR_SPYMASTER); 1717 1718 if ((error = prlock(pnp, ZNO)) != 0) 1719 return (error); 1720 1721 if (pnp->pr_common->prc_thread == NULL) { 1722 prunlock(pnp); 1723 return (0); 1724 } 1725 1726 lwp = pnp->pr_common->prc_thread->t_lwp; 1727 1728 if (lwp->lwp_spymaster == NULL) { 1729 prunlock(pnp); 1730 return (0); 1731 } 1732 1733 bcopy(lwp->lwp_spymaster, &psinfo, sizeof (psinfo_t)); 1734 prunlock(pnp); 1735 1736 return (pr_uioread(&psinfo, sizeof (psinfo), uiop)); 1737 } 1738 1739 static int 1740 pr_read_secflags(prnode_t *pnp, uio_t *uiop, cred_t *cr) 1741 { 1742 prsecflags_t ret; 1743 int error; 1744 proc_t *p; 1745 1746 ASSERT(pnp->pr_type == PR_SECFLAGS); 1747 1748 if ((error = prlock(pnp, ZNO)) != 0) 1749 return (error); 1750 1751 p = pnp->pr_common->prc_proc; 1752 prgetsecflags(p, &ret); 1753 prunlock(pnp); 1754 1755 return (pr_uioread(&ret, sizeof (ret), uiop)); 1756 } 1757 1758 #if defined(__sparc) 1759 1760 static int 1761 pr_read_gwindows(prnode_t *pnp, uio_t *uiop, cred_t *cr) 1762 { 1763 proc_t *p; 1764 kthread_t *t; 1765 gwindows_t *gwp; 1766 int error; 1767 size_t size; 1768 1769 ASSERT(pnp->pr_type == PR_GWINDOWS); 1770 1771 gwp = kmem_zalloc(sizeof (gwindows_t), KM_SLEEP); 1772 1773 if ((error = prlock(pnp, ZNO)) != 0) 1774 goto out; 1775 1776 p = pnp->pr_common->prc_proc; 1777 t = pnp->pr_common->prc_thread; 1778 1779 /* 1780 * Drop p->p_lock while touching the stack. 1781 * The P_PR_LOCK flag prevents the lwp from 1782 * disappearing while we do this. 1783 */ 1784 mutex_exit(&p->p_lock); 1785 if ((size = prnwindows(ttolwp(t))) != 0) 1786 size = sizeof (gwindows_t) - 1787 (SPARC_MAXREGWINDOW - size) * sizeof (struct rwindow); 1788 if (uiop->uio_offset >= size) { 1789 mutex_enter(&p->p_lock); 1790 prunlock(pnp); 1791 goto out; 1792 } 1793 prgetwindows(ttolwp(t), gwp); 1794 mutex_enter(&p->p_lock); 1795 prunlock(pnp); 1796 1797 error = pr_uioread(gwp, size, uiop); 1798 out: 1799 kmem_free(gwp, sizeof (gwindows_t)); 1800 return (error); 1801 } 1802 1803 /* ARGSUSED */ 1804 static int 1805 pr_read_asrs(prnode_t *pnp, uio_t *uiop, cred_t *cr) 1806 { 1807 int error; 1808 1809 ASSERT(pnp->pr_type == PR_ASRS); 1810 1811 /* the asrs file exists only for sparc v9 _LP64 processes */ 1812 if ((error = prlock(pnp, ZNO)) == 0) { 1813 proc_t *p = pnp->pr_common->prc_proc; 1814 kthread_t *t = pnp->pr_common->prc_thread; 1815 asrset_t asrset; 1816 1817 if (p->p_model != DATAMODEL_LP64 || 1818 uiop->uio_offset >= sizeof (asrset_t)) { 1819 prunlock(pnp); 1820 return (0); 1821 } 1822 1823 /* 1824 * Drop p->p_lock while touching the stack. 1825 * The P_PR_LOCK flag prevents the lwp from 1826 * disappearing while we do this. 1827 */ 1828 mutex_exit(&p->p_lock); 1829 prgetasregs(ttolwp(t), asrset); 1830 mutex_enter(&p->p_lock); 1831 prunlock(pnp); 1832 1833 error = pr_uioread(&asrset[0], sizeof (asrset_t), uiop); 1834 } 1835 1836 return (error); 1837 } 1838 1839 #endif /* __sparc */ 1840 1841 static int 1842 pr_read_piddir(prnode_t *pnp, uio_t *uiop, cred_t *cr) 1843 { 1844 ASSERT(pnp->pr_type == PR_PIDDIR); 1845 ASSERT(pnp->pr_pidfile != NULL); 1846 1847 /* use the underlying PR_PIDFILE to read the process */ 1848 pnp = VTOP(pnp->pr_pidfile); 1849 ASSERT(pnp->pr_type == PR_PIDFILE); 1850 1851 return (pr_read_pidfile(pnp, uiop)); 1852 } 1853 1854 static int 1855 pr_read_pidfile(prnode_t *pnp, uio_t *uiop, cred_t *cr) 1856 { 1857 int error; 1858 1859 ASSERT(pnp->pr_type == PR_PIDFILE || pnp->pr_type == PR_LWPIDFILE); 1860 1861 if ((error = prlock(pnp, ZNO)) == 0) { 1862 proc_t *p = pnp->pr_common->prc_proc; 1863 struct as *as = p->p_as; 1864 1865 if ((p->p_flag & SSYS) || as == &kas) { 1866 /* 1867 * /proc I/O cannot be done to a system process. 1868 */ 1869 error = EIO; /* old /proc semantics */ 1870 } else { 1871 /* 1872 * We drop p_lock because we don't want to hold 1873 * it over an I/O operation because that could 1874 * lead to deadlock with the clock thread. 1875 * The process will not disappear and its address 1876 * space will not change because it is marked P_PR_LOCK. 1877 */ 1878 mutex_exit(&p->p_lock); 1879 error = prusrio(p, UIO_READ, uiop, 1); 1880 mutex_enter(&p->p_lock); 1881 } 1882 prunlock(pnp); 1883 } 1884 1885 return (error); 1886 } 1887 1888 #ifdef _SYSCALL32_IMPL 1889 1890 /* 1891 * Array of ILP32 read functions, indexed by /proc file type. 1892 */ 1893 static int pr_read_status_32(), 1894 pr_read_lstatus_32(), pr_read_psinfo_32(), pr_read_lpsinfo_32(), 1895 pr_read_map_32(), pr_read_rmap_32(), pr_read_xmap_32(), 1896 pr_read_sigact_32(), pr_read_auxv_32(), 1897 pr_read_usage_32(), pr_read_lusage_32(), pr_read_pagedata_32(), 1898 pr_read_watch_32(), pr_read_lwpstatus_32(), pr_read_lwpsinfo_32(), 1899 pr_read_lwpusage_32(), pr_read_spymaster_32(), 1900 #if defined(__sparc) 1901 pr_read_gwindows_32(), 1902 #endif 1903 pr_read_opagedata_32(); 1904 1905 static int (*pr_read_function_32[PR_NFILES])() = { 1906 pr_read_inval, /* /proc */ 1907 pr_read_inval, /* /proc/self */ 1908 pr_read_piddir, /* /proc/<pid> (old /proc read()) */ 1909 pr_read_as, /* /proc/<pid>/as */ 1910 pr_read_inval, /* /proc/<pid>/ctl */ 1911 pr_read_status_32, /* /proc/<pid>/status */ 1912 pr_read_lstatus_32, /* /proc/<pid>/lstatus */ 1913 pr_read_psinfo_32, /* /proc/<pid>/psinfo */ 1914 pr_read_lpsinfo_32, /* /proc/<pid>/lpsinfo */ 1915 pr_read_map_32, /* /proc/<pid>/map */ 1916 pr_read_rmap_32, /* /proc/<pid>/rmap */ 1917 pr_read_xmap_32, /* /proc/<pid>/xmap */ 1918 pr_read_cred, /* /proc/<pid>/cred */ 1919 pr_read_sigact_32, /* /proc/<pid>/sigact */ 1920 pr_read_auxv_32, /* /proc/<pid>/auxv */ 1921 #if defined(__x86) 1922 pr_read_ldt, /* /proc/<pid>/ldt */ 1923 #endif 1924 pr_read_usage_32, /* /proc/<pid>/usage */ 1925 pr_read_lusage_32, /* /proc/<pid>/lusage */ 1926 pr_read_pagedata_32, /* /proc/<pid>/pagedata */ 1927 pr_read_watch_32, /* /proc/<pid>/watch */ 1928 pr_read_inval, /* /proc/<pid>/cwd */ 1929 pr_read_inval, /* /proc/<pid>/root */ 1930 pr_read_inval, /* /proc/<pid>/fd */ 1931 pr_read_inval, /* /proc/<pid>/fd/nn */ 1932 pr_read_inval, /* /proc/<pid>/fdinfo */ 1933 pr_read_fdinfo, /* /proc/<pid>/fdinfo/nn */ 1934 pr_read_inval, /* /proc/<pid>/object */ 1935 pr_read_inval, /* /proc/<pid>/object/xxx */ 1936 pr_read_inval, /* /proc/<pid>/lwp */ 1937 pr_read_inval, /* /proc/<pid>/lwp/<lwpid> */ 1938 pr_read_inval, /* /proc/<pid>/lwp/<lwpid>/lwpctl */ 1939 pr_read_lwpname, /* /proc/<pid>/lwp/<lwpid>/lwpname */ 1940 pr_read_lwpstatus_32, /* /proc/<pid>/lwp/<lwpid>/lwpstatus */ 1941 pr_read_lwpsinfo_32, /* /proc/<pid>/lwp/<lwpid>/lwpsinfo */ 1942 pr_read_lwpusage_32, /* /proc/<pid>/lwp/<lwpid>/lwpusage */ 1943 pr_read_xregs, /* /proc/<pid>/lwp/<lwpid>/xregs */ 1944 pr_read_inval, /* /proc/<pid>/lwp/<lwpid>/templates */ 1945 pr_read_inval, /* /proc/<pid>/lwp/<lwpid>/templates/<id> */ 1946 pr_read_spymaster_32, /* /proc/<pid>/lwp/<lwpid>/spymaster */ 1947 #if defined(__sparc) 1948 pr_read_gwindows_32, /* /proc/<pid>/lwp/<lwpid>/gwindows */ 1949 pr_read_asrs, /* /proc/<pid>/lwp/<lwpid>/asrs */ 1950 #endif 1951 pr_read_priv, /* /proc/<pid>/priv */ 1952 pr_read_inval, /* /proc/<pid>/path */ 1953 pr_read_inval, /* /proc/<pid>/path/xxx */ 1954 pr_read_inval, /* /proc/<pid>/contracts */ 1955 pr_read_inval, /* /proc/<pid>/contracts/<ctid> */ 1956 pr_read_secflags, /* /proc/<pid>/secflags */ 1957 pr_read_pidfile, /* old process file */ 1958 pr_read_pidfile, /* old lwp file */ 1959 pr_read_opagedata_32, /* old pagedata file */ 1960 }; 1961 1962 static int 1963 pr_read_status_32(prnode_t *pnp, uio_t *uiop, cred_t *cr) 1964 { 1965 pstatus32_t *sp; 1966 proc_t *p; 1967 int error; 1968 1969 ASSERT(pnp->pr_type == PR_STATUS); 1970 1971 /* 1972 * We kmem_alloc() the pstatus structure because 1973 * it is so big it might blow the kernel stack. 1974 */ 1975 sp = kmem_alloc(sizeof (*sp), KM_SLEEP); 1976 if ((error = prlock(pnp, ZNO)) == 0) { 1977 /* 1978 * A 32-bit process cannot get the status of a 64-bit process. 1979 * The fields for the 64-bit quantities are not large enough. 1980 */ 1981 p = pnp->pr_common->prc_proc; 1982 if (PROCESS_NOT_32BIT(p)) { 1983 prunlock(pnp); 1984 error = EOVERFLOW; 1985 } else { 1986 prgetstatus32(pnp->pr_common->prc_proc, sp, 1987 VTOZONE(PTOV(pnp))); 1988 prunlock(pnp); 1989 error = pr_uioread(sp, sizeof (*sp), uiop); 1990 } 1991 } 1992 kmem_free((caddr_t)sp, sizeof (*sp)); 1993 return (error); 1994 } 1995 1996 static int 1997 pr_read_lstatus_32(prnode_t *pnp, uio_t *uiop, cred_t *cr) 1998 { 1999 proc_t *p; 2000 kthread_t *t; 2001 lwpdir_t *ldp; 2002 size_t size; 2003 prheader32_t *php; 2004 lwpstatus32_t *sp; 2005 int error; 2006 int nlwp; 2007 int i; 2008 2009 ASSERT(pnp->pr_type == PR_LSTATUS); 2010 2011 if ((error = prlock(pnp, ZNO)) != 0) 2012 return (error); 2013 p = pnp->pr_common->prc_proc; 2014 /* 2015 * A 32-bit process cannot get the status of a 64-bit process. 2016 * The fields for the 64-bit quantities are not large enough. 2017 */ 2018 if (PROCESS_NOT_32BIT(p)) { 2019 prunlock(pnp); 2020 return (EOVERFLOW); 2021 } 2022 nlwp = p->p_lwpcnt; 2023 size = sizeof (prheader32_t) + nlwp * LSPAN32(lwpstatus32_t); 2024 2025 /* drop p->p_lock to do kmem_alloc(KM_SLEEP) */ 2026 mutex_exit(&p->p_lock); 2027 php = kmem_zalloc(size, KM_SLEEP); 2028 mutex_enter(&p->p_lock); 2029 /* p->p_lwpcnt can't change while process is locked */ 2030 ASSERT(nlwp == p->p_lwpcnt); 2031 2032 php->pr_nent = nlwp; 2033 php->pr_entsize = LSPAN32(lwpstatus32_t); 2034 2035 sp = (lwpstatus32_t *)(php + 1); 2036 for (ldp = p->p_lwpdir, i = 0; i < p->p_lwpdir_sz; i++, ldp++) { 2037 if (ldp->ld_entry == NULL || 2038 (t = ldp->ld_entry->le_thread) == NULL) 2039 continue; 2040 prgetlwpstatus32(t, sp, VTOZONE(PTOV(pnp))); 2041 sp = (lwpstatus32_t *)((caddr_t)sp + LSPAN32(lwpstatus32_t)); 2042 } 2043 prunlock(pnp); 2044 2045 error = pr_uioread(php, size, uiop); 2046 kmem_free(php, size); 2047 return (error); 2048 } 2049 2050 static int 2051 pr_read_psinfo_32(prnode_t *pnp, uio_t *uiop, cred_t *cr) 2052 { 2053 psinfo32_t psinfo; 2054 proc_t *p; 2055 int error = 0; 2056 2057 ASSERT(pnp->pr_type == PR_PSINFO); 2058 2059 /* 2060 * We don't want the full treatment of prlock(pnp) here. 2061 * This file is world-readable and never goes invalid. 2062 * It doesn't matter if we are in the middle of an exec(). 2063 */ 2064 p = pr_p_lock(pnp); 2065 mutex_exit(&pr_pidlock); 2066 if (p == NULL) 2067 error = ENOENT; 2068 else { 2069 ASSERT(p == pnp->pr_common->prc_proc); 2070 prgetpsinfo32(p, &psinfo); 2071 prunlock(pnp); 2072 error = pr_uioread(&psinfo, sizeof (psinfo), uiop); 2073 } 2074 return (error); 2075 } 2076 2077 static int 2078 pr_read_lpsinfo_32(prnode_t *pnp, uio_t *uiop, cred_t *cr) 2079 { 2080 proc_t *p; 2081 kthread_t *t; 2082 lwpdir_t *ldp; 2083 lwpent_t *lep; 2084 size_t size; 2085 prheader32_t *php; 2086 lwpsinfo32_t *sp; 2087 int error; 2088 int nlwp; 2089 int i; 2090 2091 ASSERT(pnp->pr_type == PR_LPSINFO); 2092 2093 /* 2094 * We don't want the full treatment of prlock(pnp) here. 2095 * This file is world-readable and never goes invalid. 2096 * It doesn't matter if we are in the middle of an exec(). 2097 */ 2098 p = pr_p_lock(pnp); 2099 mutex_exit(&pr_pidlock); 2100 if (p == NULL) 2101 return (ENOENT); 2102 ASSERT(p == pnp->pr_common->prc_proc); 2103 if ((nlwp = p->p_lwpcnt + p->p_zombcnt) == 0) { 2104 prunlock(pnp); 2105 return (ENOENT); 2106 } 2107 size = sizeof (prheader32_t) + nlwp * LSPAN32(lwpsinfo32_t); 2108 2109 /* drop p->p_lock to do kmem_alloc(KM_SLEEP) */ 2110 mutex_exit(&p->p_lock); 2111 php = kmem_zalloc(size, KM_SLEEP); 2112 mutex_enter(&p->p_lock); 2113 /* p->p_lwpcnt can't change while process is locked */ 2114 ASSERT(nlwp == p->p_lwpcnt + p->p_zombcnt); 2115 2116 php->pr_nent = nlwp; 2117 php->pr_entsize = LSPAN32(lwpsinfo32_t); 2118 2119 sp = (lwpsinfo32_t *)(php + 1); 2120 for (ldp = p->p_lwpdir, i = 0; i < p->p_lwpdir_sz; i++, ldp++) { 2121 if ((lep = ldp->ld_entry) == NULL) 2122 continue; 2123 if ((t = lep->le_thread) != NULL) 2124 prgetlwpsinfo32(t, sp); 2125 else { 2126 bzero(sp, sizeof (*sp)); 2127 sp->pr_lwpid = lep->le_lwpid; 2128 sp->pr_state = SZOMB; 2129 sp->pr_sname = 'Z'; 2130 sp->pr_start.tv_sec = (time32_t)lep->le_start; 2131 } 2132 sp = (lwpsinfo32_t *)((caddr_t)sp + LSPAN32(lwpsinfo32_t)); 2133 } 2134 prunlock(pnp); 2135 2136 error = pr_uioread(php, size, uiop); 2137 kmem_free(php, size); 2138 return (error); 2139 } 2140 2141 static int 2142 pr_read_map_common_32(prnode_t *pnp, uio_t *uiop, prnodetype_t type) 2143 { 2144 proc_t *p; 2145 struct as *as; 2146 list_t iolhead; 2147 int error; 2148 2149 readmap32_common: 2150 if ((error = prlock(pnp, ZNO)) != 0) 2151 return (error); 2152 2153 p = pnp->pr_common->prc_proc; 2154 as = p->p_as; 2155 2156 if ((p->p_flag & SSYS) || as == &kas) { 2157 prunlock(pnp); 2158 return (0); 2159 } 2160 2161 if (PROCESS_NOT_32BIT(p)) { 2162 prunlock(pnp); 2163 return (EOVERFLOW); 2164 } 2165 2166 if (!AS_LOCK_TRYENTER(as, RW_WRITER)) { 2167 prunlock(pnp); 2168 delay(1); 2169 goto readmap32_common; 2170 } 2171 mutex_exit(&p->p_lock); 2172 2173 switch (type) { 2174 case PR_XMAP: 2175 error = prgetxmap32(p, &iolhead); 2176 break; 2177 case PR_RMAP: 2178 error = prgetmap32(p, 1, &iolhead); 2179 break; 2180 case PR_MAP: 2181 error = prgetmap32(p, 0, &iolhead); 2182 break; 2183 } 2184 AS_LOCK_EXIT(as); 2185 mutex_enter(&p->p_lock); 2186 prunlock(pnp); 2187 2188 error = pr_iol_uiomove_and_free(&iolhead, uiop, error); 2189 2190 return (error); 2191 } 2192 2193 static int 2194 pr_read_map_32(prnode_t *pnp, uio_t *uiop, cred_t *cr) 2195 { 2196 ASSERT(pnp->pr_type == PR_MAP); 2197 return (pr_read_map_common_32(pnp, uiop, pnp->pr_type)); 2198 } 2199 2200 static int 2201 pr_read_rmap_32(prnode_t *pnp, uio_t *uiop, cred_t *cr) 2202 { 2203 ASSERT(pnp->pr_type == PR_RMAP); 2204 return (pr_read_map_common_32(pnp, uiop, pnp->pr_type)); 2205 } 2206 2207 static int 2208 pr_read_xmap_32(prnode_t *pnp, uio_t *uiop, cred_t *cr) 2209 { 2210 ASSERT(pnp->pr_type == PR_XMAP); 2211 return (pr_read_map_common_32(pnp, uiop, pnp->pr_type)); 2212 } 2213 2214 static int 2215 pr_read_sigact_32(prnode_t *pnp, uio_t *uiop, cred_t *cr) 2216 { 2217 int nsig = PROC_IS_BRANDED(curproc)? BROP(curproc)->b_nsig : NSIG; 2218 proc_t *p; 2219 struct sigaction32 *sap; 2220 int sig; 2221 int error; 2222 user_t *up; 2223 2224 ASSERT(pnp->pr_type == PR_SIGACT); 2225 2226 /* 2227 * We kmem_alloc() the sigaction32 array because 2228 * it is so big it might blow the kernel stack. 2229 */ 2230 sap = kmem_alloc((nsig-1) * sizeof (struct sigaction32), KM_SLEEP); 2231 2232 if ((error = prlock(pnp, ZNO)) != 0) 2233 goto out; 2234 p = pnp->pr_common->prc_proc; 2235 2236 if (PROCESS_NOT_32BIT(p)) { 2237 prunlock(pnp); 2238 error = EOVERFLOW; 2239 goto out; 2240 } 2241 2242 if (uiop->uio_offset >= (nsig-1) * sizeof (struct sigaction32)) { 2243 prunlock(pnp); 2244 goto out; 2245 } 2246 2247 up = PTOU(p); 2248 for (sig = 1; sig < nsig; sig++) 2249 prgetaction32(p, up, sig, &sap[sig-1]); 2250 prunlock(pnp); 2251 2252 error = pr_uioread(sap, (nsig - 1) * sizeof (struct sigaction32), uiop); 2253 out: 2254 kmem_free(sap, (nsig-1) * sizeof (struct sigaction32)); 2255 return (error); 2256 } 2257 2258 static int 2259 pr_read_auxv_32(prnode_t *pnp, uio_t *uiop, cred_t *cr) 2260 { 2261 auxv32_t auxv[__KERN_NAUXV_IMPL]; 2262 proc_t *p; 2263 user_t *up; 2264 int error; 2265 int i; 2266 2267 ASSERT(pnp->pr_type == PR_AUXV); 2268 2269 if ((error = prlock(pnp, ZNO)) != 0) 2270 return (error); 2271 p = pnp->pr_common->prc_proc; 2272 2273 if (PROCESS_NOT_32BIT(p)) { 2274 prunlock(pnp); 2275 return (EOVERFLOW); 2276 } 2277 2278 if (uiop->uio_offset >= sizeof (auxv)) { 2279 prunlock(pnp); 2280 return (0); 2281 } 2282 2283 up = PTOU(p); 2284 for (i = 0; i < __KERN_NAUXV_IMPL; i++) { 2285 auxv[i].a_type = (int32_t)up->u_auxv[i].a_type; 2286 auxv[i].a_un.a_val = (int32_t)up->u_auxv[i].a_un.a_val; 2287 } 2288 prunlock(pnp); 2289 2290 return (pr_uioread(auxv, sizeof (auxv), uiop)); 2291 } 2292 2293 static int 2294 pr_read_usage_32(prnode_t *pnp, uio_t *uiop, cred_t *cr) 2295 { 2296 prhusage_t *pup; 2297 prusage32_t *upup; 2298 proc_t *p; 2299 kthread_t *t; 2300 int error; 2301 2302 ASSERT(pnp->pr_type == PR_USAGE); 2303 2304 /* allocate now, before locking the process */ 2305 pup = kmem_zalloc(sizeof (*pup), KM_SLEEP); 2306 upup = kmem_alloc(sizeof (*upup), KM_SLEEP); 2307 2308 /* 2309 * We don't want the full treatment of prlock(pnp) here. 2310 * This file is world-readable and never goes invalid. 2311 * It doesn't matter if we are in the middle of an exec(). 2312 */ 2313 p = pr_p_lock(pnp); 2314 mutex_exit(&pr_pidlock); 2315 if (p == NULL) { 2316 error = ENOENT; 2317 goto out; 2318 } 2319 ASSERT(p == pnp->pr_common->prc_proc); 2320 2321 if (uiop->uio_offset >= sizeof (prusage32_t)) { 2322 prunlock(pnp); 2323 error = 0; 2324 goto out; 2325 } 2326 2327 pup->pr_tstamp = gethrtime(); 2328 2329 pup->pr_count = p->p_defunct; 2330 pup->pr_create = p->p_mstart; 2331 pup->pr_term = p->p_mterm; 2332 2333 pup->pr_rtime = p->p_mlreal; 2334 pup->pr_utime = p->p_acct[LMS_USER]; 2335 pup->pr_stime = p->p_acct[LMS_SYSTEM]; 2336 pup->pr_ttime = p->p_acct[LMS_TRAP]; 2337 pup->pr_tftime = p->p_acct[LMS_TFAULT]; 2338 pup->pr_dftime = p->p_acct[LMS_DFAULT]; 2339 pup->pr_kftime = p->p_acct[LMS_KFAULT]; 2340 pup->pr_ltime = p->p_acct[LMS_USER_LOCK]; 2341 pup->pr_slptime = p->p_acct[LMS_SLEEP]; 2342 pup->pr_wtime = p->p_acct[LMS_WAIT_CPU]; 2343 pup->pr_stoptime = p->p_acct[LMS_STOPPED]; 2344 2345 pup->pr_minf = p->p_ru.minflt; 2346 pup->pr_majf = p->p_ru.majflt; 2347 pup->pr_nswap = p->p_ru.nswap; 2348 pup->pr_inblk = p->p_ru.inblock; 2349 pup->pr_oublk = p->p_ru.oublock; 2350 pup->pr_msnd = p->p_ru.msgsnd; 2351 pup->pr_mrcv = p->p_ru.msgrcv; 2352 pup->pr_sigs = p->p_ru.nsignals; 2353 pup->pr_vctx = p->p_ru.nvcsw; 2354 pup->pr_ictx = p->p_ru.nivcsw; 2355 pup->pr_sysc = p->p_ru.sysc; 2356 pup->pr_ioch = p->p_ru.ioch; 2357 2358 /* 2359 * Add the usage information for each active lwp. 2360 */ 2361 if ((t = p->p_tlist) != NULL && 2362 !(pnp->pr_pcommon->prc_flags & PRC_DESTROY)) { 2363 do { 2364 if (t->t_proc_flag & TP_LWPEXIT) 2365 continue; 2366 pup->pr_count++; 2367 praddusage(t, pup); 2368 } while ((t = t->t_forw) != p->p_tlist); 2369 } 2370 2371 prunlock(pnp); 2372 2373 prcvtusage32(pup, upup); 2374 2375 error = pr_uioread(upup, sizeof (prusage32_t), uiop); 2376 out: 2377 kmem_free(pup, sizeof (*pup)); 2378 kmem_free(upup, sizeof (*upup)); 2379 return (error); 2380 } 2381 2382 static int 2383 pr_read_lusage_32(prnode_t *pnp, uio_t *uiop, cred_t *cr) 2384 { 2385 int nlwp; 2386 prhusage_t *pup; 2387 prheader32_t *php; 2388 prusage32_t *upup; 2389 size_t size; 2390 hrtime_t curtime; 2391 proc_t *p; 2392 kthread_t *t; 2393 lwpdir_t *ldp; 2394 int error; 2395 int i; 2396 2397 ASSERT(pnp->pr_type == PR_LUSAGE); 2398 2399 /* 2400 * We don't want the full treatment of prlock(pnp) here. 2401 * This file is world-readable and never goes invalid. 2402 * It doesn't matter if we are in the middle of an exec(). 2403 */ 2404 p = pr_p_lock(pnp); 2405 mutex_exit(&pr_pidlock); 2406 if (p == NULL) 2407 return (ENOENT); 2408 ASSERT(p == pnp->pr_common->prc_proc); 2409 if ((nlwp = p->p_lwpcnt) == 0) { 2410 prunlock(pnp); 2411 return (ENOENT); 2412 } 2413 2414 size = sizeof (prheader32_t) + (nlwp + 1) * LSPAN32(prusage32_t); 2415 if (uiop->uio_offset >= size) { 2416 prunlock(pnp); 2417 return (0); 2418 } 2419 2420 /* drop p->p_lock to do kmem_alloc(KM_SLEEP) */ 2421 mutex_exit(&p->p_lock); 2422 pup = kmem_zalloc(size + sizeof (prhusage_t), KM_SLEEP); 2423 mutex_enter(&p->p_lock); 2424 /* p->p_lwpcnt can't change while process is locked */ 2425 ASSERT(nlwp == p->p_lwpcnt); 2426 2427 php = (prheader32_t *)(pup + 1); 2428 upup = (prusage32_t *)(php + 1); 2429 2430 php->pr_nent = nlwp + 1; 2431 php->pr_entsize = LSPAN32(prusage32_t); 2432 2433 curtime = gethrtime(); 2434 2435 /* 2436 * First the summation over defunct lwps. 2437 */ 2438 pup->pr_count = p->p_defunct; 2439 pup->pr_tstamp = curtime; 2440 pup->pr_create = p->p_mstart; 2441 pup->pr_term = p->p_mterm; 2442 2443 pup->pr_rtime = p->p_mlreal; 2444 pup->pr_utime = p->p_acct[LMS_USER]; 2445 pup->pr_stime = p->p_acct[LMS_SYSTEM]; 2446 pup->pr_ttime = p->p_acct[LMS_TRAP]; 2447 pup->pr_tftime = p->p_acct[LMS_TFAULT]; 2448 pup->pr_dftime = p->p_acct[LMS_DFAULT]; 2449 pup->pr_kftime = p->p_acct[LMS_KFAULT]; 2450 pup->pr_ltime = p->p_acct[LMS_USER_LOCK]; 2451 pup->pr_slptime = p->p_acct[LMS_SLEEP]; 2452 pup->pr_wtime = p->p_acct[LMS_WAIT_CPU]; 2453 pup->pr_stoptime = p->p_acct[LMS_STOPPED]; 2454 2455 pup->pr_minf = p->p_ru.minflt; 2456 pup->pr_majf = p->p_ru.majflt; 2457 pup->pr_nswap = p->p_ru.nswap; 2458 pup->pr_inblk = p->p_ru.inblock; 2459 pup->pr_oublk = p->p_ru.oublock; 2460 pup->pr_msnd = p->p_ru.msgsnd; 2461 pup->pr_mrcv = p->p_ru.msgrcv; 2462 pup->pr_sigs = p->p_ru.nsignals; 2463 pup->pr_vctx = p->p_ru.nvcsw; 2464 pup->pr_ictx = p->p_ru.nivcsw; 2465 pup->pr_sysc = p->p_ru.sysc; 2466 pup->pr_ioch = p->p_ru.ioch; 2467 2468 prcvtusage32(pup, upup); 2469 2470 /* 2471 * Fill one prusage struct for each active lwp. 2472 */ 2473 for (ldp = p->p_lwpdir, i = 0; i < p->p_lwpdir_sz; i++, ldp++) { 2474 if (ldp->ld_entry == NULL || 2475 (t = ldp->ld_entry->le_thread) == NULL) 2476 continue; 2477 ASSERT(!(t->t_proc_flag & TP_LWPEXIT)); 2478 ASSERT(nlwp > 0); 2479 --nlwp; 2480 upup = (prusage32_t *) 2481 ((caddr_t)upup + LSPAN32(prusage32_t)); 2482 prgetusage(t, pup); 2483 prcvtusage32(pup, upup); 2484 } 2485 ASSERT(nlwp == 0); 2486 2487 prunlock(pnp); 2488 2489 error = pr_uioread(php, size, uiop); 2490 kmem_free(pup, size + sizeof (prhusage_t)); 2491 return (error); 2492 } 2493 2494 static int 2495 pr_read_pagedata_32(prnode_t *pnp, uio_t *uiop, cred_t *cr) 2496 { 2497 proc_t *p; 2498 int error; 2499 2500 ASSERT(pnp->pr_type == PR_PAGEDATA); 2501 2502 if ((error = prlock(pnp, ZNO)) != 0) 2503 return (error); 2504 2505 p = pnp->pr_common->prc_proc; 2506 if ((p->p_flag & SSYS) || p->p_as == &kas) { 2507 prunlock(pnp); 2508 return (0); 2509 } 2510 2511 if (PROCESS_NOT_32BIT(p)) { 2512 prunlock(pnp); 2513 return (EOVERFLOW); 2514 } 2515 2516 mutex_exit(&p->p_lock); 2517 error = prpdread32(p, pnp->pr_hatid, uiop); 2518 mutex_enter(&p->p_lock); 2519 2520 prunlock(pnp); 2521 return (error); 2522 } 2523 2524 static int 2525 pr_read_opagedata_32(prnode_t *pnp, uio_t *uiop, cred_t *cr) 2526 { 2527 proc_t *p; 2528 struct as *as; 2529 int error; 2530 2531 ASSERT(pnp->pr_type == PR_OPAGEDATA); 2532 2533 if ((error = prlock(pnp, ZNO)) != 0) 2534 return (error); 2535 2536 p = pnp->pr_common->prc_proc; 2537 as = p->p_as; 2538 2539 if ((p->p_flag & SSYS) || as == &kas) { 2540 prunlock(pnp); 2541 return (0); 2542 } 2543 2544 if (PROCESS_NOT_32BIT(p)) { 2545 prunlock(pnp); 2546 return (EOVERFLOW); 2547 } 2548 2549 mutex_exit(&p->p_lock); 2550 error = oprpdread32(as, pnp->pr_hatid, uiop); 2551 mutex_enter(&p->p_lock); 2552 2553 prunlock(pnp); 2554 return (error); 2555 } 2556 2557 static int 2558 pr_read_watch_32(prnode_t *pnp, uio_t *uiop, cred_t *cr) 2559 { 2560 proc_t *p; 2561 int error; 2562 prwatch32_t *Bpwp; 2563 size_t size; 2564 prwatch32_t *pwp; 2565 int nwarea; 2566 struct watched_area *pwarea; 2567 2568 ASSERT(pnp->pr_type == PR_WATCH); 2569 2570 if ((error = prlock(pnp, ZNO)) != 0) 2571 return (error); 2572 2573 p = pnp->pr_common->prc_proc; 2574 if (PROCESS_NOT_32BIT(p)) { 2575 prunlock(pnp); 2576 return (EOVERFLOW); 2577 } 2578 nwarea = avl_numnodes(&p->p_warea); 2579 size = nwarea * sizeof (prwatch32_t); 2580 if (uiop->uio_offset >= size) { 2581 prunlock(pnp); 2582 return (0); 2583 } 2584 2585 /* drop p->p_lock to do kmem_alloc(KM_SLEEP) */ 2586 mutex_exit(&p->p_lock); 2587 Bpwp = pwp = kmem_zalloc(size, KM_SLEEP); 2588 mutex_enter(&p->p_lock); 2589 /* p->p_nwarea can't change while process is locked */ 2590 ASSERT(nwarea == avl_numnodes(&p->p_warea)); 2591 2592 /* gather the watched areas */ 2593 for (pwarea = avl_first(&p->p_warea); pwarea != NULL; 2594 pwarea = AVL_NEXT(&p->p_warea, pwarea), pwp++) { 2595 pwp->pr_vaddr = (caddr32_t)(uintptr_t)pwarea->wa_vaddr; 2596 pwp->pr_size = (size32_t)(pwarea->wa_eaddr - pwarea->wa_vaddr); 2597 pwp->pr_wflags = (int)pwarea->wa_flags; 2598 } 2599 2600 prunlock(pnp); 2601 2602 error = pr_uioread(Bpwp, size, uiop); 2603 kmem_free(Bpwp, size); 2604 return (error); 2605 } 2606 2607 static int 2608 pr_read_lwpstatus_32(prnode_t *pnp, uio_t *uiop, cred_t *cr) 2609 { 2610 lwpstatus32_t *sp; 2611 proc_t *p; 2612 int error; 2613 2614 ASSERT(pnp->pr_type == PR_LWPSTATUS); 2615 2616 /* 2617 * We kmem_alloc() the lwpstatus structure because 2618 * it is so big it might blow the kernel stack. 2619 */ 2620 sp = kmem_alloc(sizeof (*sp), KM_SLEEP); 2621 2622 if ((error = prlock(pnp, ZNO)) != 0) 2623 goto out; 2624 2625 /* 2626 * A 32-bit process cannot get the status of a 64-bit process. 2627 * The fields for the 64-bit quantities are not large enough. 2628 */ 2629 p = pnp->pr_common->prc_proc; 2630 if (PROCESS_NOT_32BIT(p)) { 2631 prunlock(pnp); 2632 error = EOVERFLOW; 2633 goto out; 2634 } 2635 2636 if (uiop->uio_offset >= sizeof (*sp)) { 2637 prunlock(pnp); 2638 goto out; 2639 } 2640 2641 prgetlwpstatus32(pnp->pr_common->prc_thread, sp, VTOZONE(PTOV(pnp))); 2642 prunlock(pnp); 2643 2644 error = pr_uioread(sp, sizeof (*sp), uiop); 2645 out: 2646 kmem_free(sp, sizeof (*sp)); 2647 return (error); 2648 } 2649 2650 static int 2651 pr_read_lwpsinfo_32(prnode_t *pnp, uio_t *uiop, cred_t *cr) 2652 { 2653 lwpsinfo32_t lwpsinfo; 2654 proc_t *p; 2655 kthread_t *t; 2656 lwpent_t *lep; 2657 2658 ASSERT(pnp->pr_type == PR_LWPSINFO); 2659 2660 /* 2661 * We don't want the full treatment of prlock(pnp) here. 2662 * This file is world-readable and never goes invalid. 2663 * It doesn't matter if we are in the middle of an exec(). 2664 */ 2665 p = pr_p_lock(pnp); 2666 mutex_exit(&pr_pidlock); 2667 if (p == NULL) 2668 return (ENOENT); 2669 ASSERT(p == pnp->pr_common->prc_proc); 2670 if (pnp->pr_common->prc_tslot == -1) { 2671 prunlock(pnp); 2672 return (ENOENT); 2673 } 2674 2675 if (uiop->uio_offset >= sizeof (lwpsinfo)) { 2676 prunlock(pnp); 2677 return (0); 2678 } 2679 2680 if ((t = pnp->pr_common->prc_thread) != NULL) 2681 prgetlwpsinfo32(t, &lwpsinfo); 2682 else { 2683 lep = p->p_lwpdir[pnp->pr_common->prc_tslot].ld_entry; 2684 bzero(&lwpsinfo, sizeof (lwpsinfo)); 2685 lwpsinfo.pr_lwpid = lep->le_lwpid; 2686 lwpsinfo.pr_state = SZOMB; 2687 lwpsinfo.pr_sname = 'Z'; 2688 lwpsinfo.pr_start.tv_sec = (time32_t)lep->le_start; 2689 } 2690 prunlock(pnp); 2691 2692 return (pr_uioread(&lwpsinfo, sizeof (lwpsinfo), uiop)); 2693 } 2694 2695 static int 2696 pr_read_lwpusage_32(prnode_t *pnp, uio_t *uiop, cred_t *cr) 2697 { 2698 prhusage_t *pup; 2699 prusage32_t *upup; 2700 proc_t *p; 2701 int error; 2702 2703 ASSERT(pnp->pr_type == PR_LWPUSAGE); 2704 2705 /* allocate now, before locking the process */ 2706 pup = kmem_zalloc(sizeof (*pup), KM_SLEEP); 2707 upup = kmem_alloc(sizeof (*upup), KM_SLEEP); 2708 2709 /* 2710 * We don't want the full treatment of prlock(pnp) here. 2711 * This file is world-readable and never goes invalid. 2712 * It doesn't matter if we are in the middle of an exec(). 2713 */ 2714 p = pr_p_lock(pnp); 2715 mutex_exit(&pr_pidlock); 2716 if (p == NULL) { 2717 error = ENOENT; 2718 goto out; 2719 } 2720 ASSERT(p == pnp->pr_common->prc_proc); 2721 if (pnp->pr_common->prc_thread == NULL) { 2722 prunlock(pnp); 2723 error = ENOENT; 2724 goto out; 2725 } 2726 if (uiop->uio_offset >= sizeof (prusage32_t)) { 2727 prunlock(pnp); 2728 error = 0; 2729 goto out; 2730 } 2731 2732 pup->pr_tstamp = gethrtime(); 2733 prgetusage(pnp->pr_common->prc_thread, pup); 2734 2735 prunlock(pnp); 2736 2737 prcvtusage32(pup, upup); 2738 2739 error = pr_uioread(upup, sizeof (prusage32_t), uiop); 2740 out: 2741 kmem_free(pup, sizeof (*pup)); 2742 kmem_free(upup, sizeof (*upup)); 2743 return (error); 2744 } 2745 2746 static int 2747 pr_read_spymaster_32(prnode_t *pnp, uio_t *uiop, cred_t *cr) 2748 { 2749 psinfo32_t psinfo; 2750 int error; 2751 klwp_t *lwp; 2752 2753 ASSERT(pnp->pr_type == PR_SPYMASTER); 2754 2755 if ((error = prlock(pnp, ZNO)) != 0) 2756 return (error); 2757 2758 if (pnp->pr_common->prc_thread == NULL) { 2759 prunlock(pnp); 2760 return (0); 2761 } 2762 2763 lwp = pnp->pr_common->prc_thread->t_lwp; 2764 2765 if (lwp->lwp_spymaster == NULL) { 2766 prunlock(pnp); 2767 return (0); 2768 } 2769 2770 psinfo_kto32(lwp->lwp_spymaster, &psinfo); 2771 prunlock(pnp); 2772 2773 return (pr_uioread(&psinfo, sizeof (psinfo), uiop)); 2774 } 2775 2776 #if defined(__sparc) 2777 static int 2778 pr_read_gwindows_32(prnode_t *pnp, uio_t *uiop, cred_t *cr) 2779 { 2780 proc_t *p; 2781 kthread_t *t; 2782 gwindows32_t *gwp; 2783 int error; 2784 size_t size; 2785 2786 ASSERT(pnp->pr_type == PR_GWINDOWS); 2787 2788 gwp = kmem_zalloc(sizeof (gwindows32_t), KM_SLEEP); 2789 2790 if ((error = prlock(pnp, ZNO)) != 0) 2791 goto out; 2792 2793 p = pnp->pr_common->prc_proc; 2794 t = pnp->pr_common->prc_thread; 2795 2796 if (PROCESS_NOT_32BIT(p)) { 2797 prunlock(pnp); 2798 error = EOVERFLOW; 2799 goto out; 2800 } 2801 2802 /* 2803 * Drop p->p_lock while touching the stack. 2804 * The P_PR_LOCK flag prevents the lwp from 2805 * disappearing while we do this. 2806 */ 2807 mutex_exit(&p->p_lock); 2808 if ((size = prnwindows(ttolwp(t))) != 0) 2809 size = sizeof (gwindows32_t) - 2810 (SPARC_MAXREGWINDOW - size) * sizeof (struct rwindow32); 2811 if (uiop->uio_offset >= size) { 2812 mutex_enter(&p->p_lock); 2813 prunlock(pnp); 2814 goto out; 2815 } 2816 prgetwindows32(ttolwp(t), gwp); 2817 mutex_enter(&p->p_lock); 2818 prunlock(pnp); 2819 2820 error = pr_uioread(gwp, size, uiop); 2821 out: 2822 kmem_free(gwp, sizeof (gwindows32_t)); 2823 return (error); 2824 } 2825 #endif /* __sparc */ 2826 2827 #endif /* _SYSCALL32_IMPL */ 2828 2829 /* ARGSUSED */ 2830 static int 2831 prread(vnode_t *vp, uio_t *uiop, int ioflag, cred_t *cr, caller_context_t *ct) 2832 { 2833 prnode_t *pnp = VTOP(vp); 2834 2835 ASSERT(pnp->pr_type < PR_NFILES); 2836 2837 #ifdef _SYSCALL32_IMPL 2838 /* 2839 * What is read from the /proc files depends on the data 2840 * model of the caller. An LP64 process will see LP64 2841 * data. An ILP32 process will see ILP32 data. 2842 */ 2843 if (curproc->p_model == DATAMODEL_LP64) 2844 return (pr_read_function[pnp->pr_type](pnp, uiop, cr)); 2845 else 2846 return (pr_read_function_32[pnp->pr_type](pnp, uiop, cr)); 2847 #else 2848 return (pr_read_function[pnp->pr_type](pnp, uiop, cr)); 2849 #endif 2850 } 2851 2852 /* Note we intentionally don't handle partial writes/updates. */ 2853 static int 2854 pr_write_lwpname(prnode_t *pnp, uio_t *uiop) 2855 { 2856 kthread_t *t = NULL; 2857 char *lwpname; 2858 int error; 2859 2860 lwpname = kmem_zalloc(THREAD_NAME_MAX, KM_SLEEP); 2861 2862 if ((error = uiomove(lwpname, THREAD_NAME_MAX, UIO_WRITE, uiop)) != 0) { 2863 kmem_free(lwpname, THREAD_NAME_MAX); 2864 return (error); 2865 } 2866 2867 /* Somebody tried to write too long a thread name... */ 2868 if (lwpname[THREAD_NAME_MAX - 1] != '\0' || uiop->uio_resid > 0) { 2869 kmem_free(lwpname, THREAD_NAME_MAX); 2870 return (EIO); 2871 } 2872 2873 VERIFY3U(lwpname[THREAD_NAME_MAX - 1], ==, '\0'); 2874 2875 for (size_t i = 0; lwpname[i] != '\0'; i++) { 2876 if (!ISPRINT(lwpname[i])) { 2877 kmem_free(lwpname, THREAD_NAME_MAX); 2878 return (EINVAL); 2879 } 2880 } 2881 2882 /* Equivalent of thread_setname(), but with the ZNO magic. */ 2883 if ((error = prlock(pnp, ZNO)) != 0) { 2884 kmem_free(lwpname, THREAD_NAME_MAX); 2885 return (error); 2886 } 2887 2888 t = pnp->pr_common->prc_thread; 2889 if (t->t_name == NULL) { 2890 t->t_name = lwpname; 2891 } else { 2892 (void) strlcpy(t->t_name, lwpname, THREAD_NAME_MAX); 2893 kmem_free(lwpname, THREAD_NAME_MAX); 2894 } 2895 2896 prunlock(pnp); 2897 return (0); 2898 } 2899 2900 /* ARGSUSED */ 2901 static int 2902 prwrite(vnode_t *vp, uio_t *uiop, int ioflag, cred_t *cr, caller_context_t *ct) 2903 { 2904 prnode_t *pnp = VTOP(vp); 2905 int old = 0; 2906 int error; 2907 ssize_t resid; 2908 2909 ASSERT(pnp->pr_type < PR_NFILES); 2910 2911 /* 2912 * Only a handful of /proc files are writable, enumerate them here. 2913 */ 2914 switch (pnp->pr_type) { 2915 case PR_PIDDIR: /* directory write()s: visceral revulsion. */ 2916 ASSERT(pnp->pr_pidfile != NULL); 2917 /* use the underlying PR_PIDFILE to write the process */ 2918 vp = pnp->pr_pidfile; 2919 pnp = VTOP(vp); 2920 ASSERT(pnp->pr_type == PR_PIDFILE); 2921 /* FALLTHROUGH */ 2922 case PR_PIDFILE: 2923 case PR_LWPIDFILE: 2924 old = 1; 2925 /* FALLTHROUGH */ 2926 case PR_AS: 2927 if ((error = prlock(pnp, ZNO)) == 0) { 2928 proc_t *p = pnp->pr_common->prc_proc; 2929 struct as *as = p->p_as; 2930 2931 if ((p->p_flag & SSYS) || as == &kas) { 2932 /* 2933 * /proc I/O cannot be done to a system process. 2934 */ 2935 error = EIO; 2936 #ifdef _SYSCALL32_IMPL 2937 } else if (curproc->p_model == DATAMODEL_ILP32 && 2938 PROCESS_NOT_32BIT(p)) { 2939 error = EOVERFLOW; 2940 #endif 2941 } else { 2942 /* 2943 * See comments above (pr_read_pidfile) 2944 * about this locking dance. 2945 */ 2946 mutex_exit(&p->p_lock); 2947 error = prusrio(p, UIO_WRITE, uiop, old); 2948 mutex_enter(&p->p_lock); 2949 } 2950 prunlock(pnp); 2951 } 2952 return (error); 2953 2954 case PR_CTL: 2955 case PR_LWPCTL: 2956 resid = uiop->uio_resid; 2957 /* 2958 * Perform the action on the control file 2959 * by passing curthreads credentials 2960 * and not target process's credentials. 2961 */ 2962 #ifdef _SYSCALL32_IMPL 2963 if (curproc->p_model == DATAMODEL_ILP32) 2964 error = prwritectl32(vp, uiop, CRED()); 2965 else 2966 error = prwritectl(vp, uiop, CRED()); 2967 #else 2968 error = prwritectl(vp, uiop, CRED()); 2969 #endif 2970 /* 2971 * This hack makes sure that the EINTR is passed 2972 * all the way back to the caller's write() call. 2973 */ 2974 if (error == EINTR) 2975 uiop->uio_resid = resid; 2976 return (error); 2977 2978 case PR_LWPNAME: 2979 return (pr_write_lwpname(pnp, uiop)); 2980 2981 default: 2982 return ((vp->v_type == VDIR)? EISDIR : EBADF); 2983 } 2984 /* NOTREACHED */ 2985 } 2986 2987 static int 2988 prgetattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr, 2989 caller_context_t *ct) 2990 { 2991 prnode_t *pnp = VTOP(vp); 2992 prnodetype_t type = pnp->pr_type; 2993 prcommon_t *pcp; 2994 proc_t *p; 2995 struct as *as; 2996 int error; 2997 vnode_t *rvp; 2998 timestruc_t now; 2999 extern uint_t nproc; 3000 int ngroups; 3001 int nsig; 3002 3003 /* 3004 * This ugly bit of code allows us to keep both versions of this 3005 * function from the same source. 3006 */ 3007 #ifdef _LP64 3008 int iam32bit = (curproc->p_model == DATAMODEL_ILP32); 3009 #define PR_OBJSIZE(obj32, obj64) \ 3010 (iam32bit ? sizeof (obj32) : sizeof (obj64)) 3011 #define PR_OBJSPAN(obj32, obj64) \ 3012 (iam32bit ? LSPAN32(obj32) : LSPAN(obj64)) 3013 #else 3014 #define PR_OBJSIZE(obj32, obj64) \ 3015 (sizeof (obj64)) 3016 #define PR_OBJSPAN(obj32, obj64) \ 3017 (LSPAN(obj64)) 3018 #endif 3019 3020 /* 3021 * Return all the attributes. Should be refined 3022 * so that it returns only those asked for. 3023 * Most of this is complete fakery anyway. 3024 */ 3025 3026 /* 3027 * For files in the /proc/<pid>/object directory, 3028 * return the attributes of the underlying object. 3029 * For files in the /proc/<pid>/fd directory, 3030 * return the attributes of the underlying file, but 3031 * make it look inaccessible if it is not a regular file. 3032 * Make directories look like symlinks. 3033 */ 3034 switch (type) { 3035 case PR_CURDIR: 3036 case PR_ROOTDIR: 3037 if (!(flags & ATTR_REAL)) 3038 break; 3039 /* restrict full knowledge of the attributes to owner or root */ 3040 if ((error = praccess(vp, 0, 0, cr, ct)) != 0) 3041 return (error); 3042 /* FALLTHROUGH */ 3043 case PR_OBJECT: 3044 case PR_FD: 3045 rvp = pnp->pr_realvp; 3046 error = VOP_GETATTR(rvp, vap, flags, cr, ct); 3047 if (error) 3048 return (error); 3049 if (type == PR_FD) { 3050 if (rvp->v_type != VREG && rvp->v_type != VDIR) 3051 vap->va_mode = 0; 3052 else 3053 vap->va_mode &= pnp->pr_mode; 3054 } 3055 if (type == PR_OBJECT) 3056 vap->va_mode &= 07555; 3057 if (rvp->v_type == VDIR && !(flags & ATTR_REAL)) { 3058 vap->va_type = VLNK; 3059 vap->va_size = 0; 3060 vap->va_nlink = 1; 3061 } 3062 return (0); 3063 default: 3064 break; 3065 } 3066 3067 bzero(vap, sizeof (*vap)); 3068 /* 3069 * Large Files: Internally proc now uses VPROC to indicate 3070 * a proc file. Since we have been returning VREG through 3071 * VOP_GETATTR() until now, we continue to do this so as 3072 * not to break apps depending on this return value. 3073 */ 3074 vap->va_type = (vp->v_type == VPROC) ? VREG : vp->v_type; 3075 vap->va_mode = pnp->pr_mode; 3076 vap->va_fsid = vp->v_vfsp->vfs_dev; 3077 vap->va_blksize = DEV_BSIZE; 3078 vap->va_rdev = 0; 3079 vap->va_seq = 0; 3080 3081 if (type == PR_PROCDIR) { 3082 vap->va_uid = 0; 3083 vap->va_gid = 0; 3084 vap->va_nlink = nproc + 2; 3085 vap->va_nodeid = (ino64_t)PRROOTINO; 3086 gethrestime(&now); 3087 vap->va_atime = vap->va_mtime = vap->va_ctime = now; 3088 vap->va_size = (v.v_proc + 2) * PRSDSIZE; 3089 vap->va_nblocks = btod(vap->va_size); 3090 return (0); 3091 } 3092 3093 /* 3094 * /proc/<pid>/self is a symbolic link, and has no prcommon member 3095 */ 3096 if (type == PR_SELF) { 3097 vap->va_uid = crgetruid(CRED()); 3098 vap->va_gid = crgetrgid(CRED()); 3099 vap->va_nodeid = (ino64_t)PR_SELF; 3100 gethrestime(&now); 3101 vap->va_atime = vap->va_mtime = vap->va_ctime = now; 3102 vap->va_nlink = 1; 3103 vap->va_type = VLNK; 3104 vap->va_size = 0; 3105 return (0); 3106 } 3107 3108 p = pr_p_lock(pnp); 3109 mutex_exit(&pr_pidlock); 3110 if (p == NULL) 3111 return (ENOENT); 3112 pcp = pnp->pr_common; 3113 3114 mutex_enter(&p->p_crlock); 3115 vap->va_uid = crgetruid(p->p_cred); 3116 vap->va_gid = crgetrgid(p->p_cred); 3117 mutex_exit(&p->p_crlock); 3118 3119 vap->va_nlink = 1; 3120 vap->va_nodeid = pnp->pr_ino? pnp->pr_ino : 3121 pmkino(pcp->prc_tslot, pcp->prc_slot, pnp->pr_type); 3122 if ((pcp->prc_flags & PRC_LWP) && pcp->prc_tslot != -1) { 3123 vap->va_atime.tv_sec = vap->va_mtime.tv_sec = 3124 vap->va_ctime.tv_sec = 3125 p->p_lwpdir[pcp->prc_tslot].ld_entry->le_start; 3126 vap->va_atime.tv_nsec = vap->va_mtime.tv_nsec = 3127 vap->va_ctime.tv_nsec = 0; 3128 } else { 3129 user_t *up = PTOU(p); 3130 vap->va_atime.tv_sec = vap->va_mtime.tv_sec = 3131 vap->va_ctime.tv_sec = up->u_start.tv_sec; 3132 vap->va_atime.tv_nsec = vap->va_mtime.tv_nsec = 3133 vap->va_ctime.tv_nsec = up->u_start.tv_nsec; 3134 } 3135 3136 switch (type) { 3137 case PR_PIDDIR: 3138 /* va_nlink: count 'lwp', 'object' and 'fd' directory links */ 3139 vap->va_nlink = 5; 3140 vap->va_size = sizeof (piddir); 3141 break; 3142 case PR_OBJECTDIR: 3143 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) 3144 vap->va_size = 2 * PRSDSIZE; 3145 else { 3146 mutex_exit(&p->p_lock); 3147 AS_LOCK_ENTER(as, RW_WRITER); 3148 if (as->a_updatedir) 3149 rebuild_objdir(as); 3150 vap->va_size = (as->a_sizedir + 2) * PRSDSIZE; 3151 AS_LOCK_EXIT(as); 3152 mutex_enter(&p->p_lock); 3153 } 3154 vap->va_nlink = 2; 3155 break; 3156 case PR_PATHDIR: 3157 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) 3158 vap->va_size = (P_FINFO(p)->fi_nfiles + 4) * PRSDSIZE; 3159 else { 3160 mutex_exit(&p->p_lock); 3161 AS_LOCK_ENTER(as, RW_WRITER); 3162 if (as->a_updatedir) 3163 rebuild_objdir(as); 3164 vap->va_size = (as->a_sizedir + 4 + 3165 P_FINFO(p)->fi_nfiles) * PRSDSIZE; 3166 AS_LOCK_EXIT(as); 3167 mutex_enter(&p->p_lock); 3168 } 3169 vap->va_nlink = 2; 3170 break; 3171 case PR_PATH: 3172 case PR_CURDIR: 3173 case PR_ROOTDIR: 3174 case PR_CT: 3175 vap->va_type = VLNK; 3176 vap->va_size = 0; 3177 break; 3178 case PR_FDDIR: 3179 case PR_FDINFODIR: 3180 vap->va_nlink = 2; 3181 vap->va_size = (P_FINFO(p)->fi_nfiles + 2) * PRSDSIZE; 3182 break; 3183 case PR_FDINFO: { 3184 file_t *fp; 3185 vnode_t *vp; 3186 int fd = pnp->pr_index; 3187 3188 fp = pr_getf(p, fd, NULL); 3189 if (fp == NULL) { 3190 prunlock(pnp); 3191 return (ENOENT); 3192 } 3193 vp = fp->f_vnode; 3194 VN_HOLD(vp); 3195 pr_releasef(p, fd); 3196 prunlock(pnp); 3197 vap->va_size = prgetfdinfosize(p, vp, cr); 3198 VN_RELE(vp); 3199 vap->va_nblocks = (fsblkcnt64_t)btod(vap->va_size); 3200 return (0); 3201 } 3202 case PR_LWPDIR: 3203 /* 3204 * va_nlink: count each lwp as a directory link. 3205 * va_size: size of p_lwpdir + 2 3206 */ 3207 vap->va_nlink = p->p_lwpcnt + p->p_zombcnt + 2; 3208 vap->va_size = (p->p_lwpdir_sz + 2) * PRSDSIZE; 3209 break; 3210 case PR_LWPIDDIR: 3211 vap->va_nlink = 2; 3212 vap->va_size = sizeof (lwpiddir); 3213 break; 3214 case PR_CTDIR: 3215 vap->va_nlink = 2; 3216 vap->va_size = (avl_numnodes(&p->p_ct_held) + 2) * PRSDSIZE; 3217 break; 3218 case PR_TMPLDIR: 3219 vap->va_nlink = 2; 3220 vap->va_size = (ct_ntypes + 2) * PRSDSIZE; 3221 break; 3222 case PR_AS: 3223 case PR_PIDFILE: 3224 case PR_LWPIDFILE: 3225 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) 3226 vap->va_size = 0; 3227 else 3228 vap->va_size = as->a_resvsize; 3229 break; 3230 case PR_STATUS: 3231 vap->va_size = PR_OBJSIZE(pstatus32_t, pstatus_t); 3232 break; 3233 case PR_LSTATUS: 3234 vap->va_size = PR_OBJSIZE(prheader32_t, prheader_t) + 3235 p->p_lwpcnt * PR_OBJSPAN(lwpstatus32_t, lwpstatus_t); 3236 break; 3237 case PR_PSINFO: 3238 vap->va_size = PR_OBJSIZE(psinfo32_t, psinfo_t); 3239 break; 3240 case PR_LPSINFO: 3241 vap->va_size = PR_OBJSIZE(prheader32_t, prheader_t) + 3242 (p->p_lwpcnt + p->p_zombcnt) * 3243 PR_OBJSPAN(lwpsinfo32_t, lwpsinfo_t); 3244 break; 3245 case PR_MAP: 3246 case PR_RMAP: 3247 case PR_XMAP: 3248 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) 3249 vap->va_size = 0; 3250 else { 3251 mutex_exit(&p->p_lock); 3252 AS_LOCK_ENTER(as, RW_WRITER); 3253 if (type == PR_MAP) 3254 vap->va_mtime = as->a_updatetime; 3255 if (type == PR_XMAP) 3256 vap->va_size = prnsegs(as, 0) * 3257 PR_OBJSIZE(prxmap32_t, prxmap_t); 3258 else 3259 vap->va_size = prnsegs(as, type == PR_RMAP) * 3260 PR_OBJSIZE(prmap32_t, prmap_t); 3261 AS_LOCK_EXIT(as); 3262 mutex_enter(&p->p_lock); 3263 } 3264 break; 3265 case PR_CRED: 3266 mutex_enter(&p->p_crlock); 3267 vap->va_size = sizeof (prcred_t); 3268 ngroups = crgetngroups(p->p_cred); 3269 if (ngroups > 1) 3270 vap->va_size += (ngroups - 1) * sizeof (gid_t); 3271 mutex_exit(&p->p_crlock); 3272 break; 3273 case PR_PRIV: 3274 vap->va_size = prgetprivsize(); 3275 break; 3276 case PR_SECFLAGS: 3277 vap->va_size = sizeof (prsecflags_t); 3278 break; 3279 case PR_SIGACT: 3280 nsig = PROC_IS_BRANDED(curproc)? BROP(curproc)->b_nsig : NSIG; 3281 vap->va_size = (nsig-1) * 3282 PR_OBJSIZE(struct sigaction32, struct sigaction); 3283 break; 3284 case PR_AUXV: 3285 vap->va_size = __KERN_NAUXV_IMPL * PR_OBJSIZE(auxv32_t, auxv_t); 3286 break; 3287 #if defined(__x86) 3288 case PR_LDT: 3289 mutex_exit(&p->p_lock); 3290 mutex_enter(&p->p_ldtlock); 3291 vap->va_size = prnldt(p) * sizeof (struct ssd); 3292 mutex_exit(&p->p_ldtlock); 3293 mutex_enter(&p->p_lock); 3294 break; 3295 #endif 3296 case PR_USAGE: 3297 vap->va_size = PR_OBJSIZE(prusage32_t, prusage_t); 3298 break; 3299 case PR_LUSAGE: 3300 vap->va_size = PR_OBJSIZE(prheader32_t, prheader_t) + 3301 (p->p_lwpcnt + 1) * PR_OBJSPAN(prusage32_t, prusage_t); 3302 break; 3303 case PR_PAGEDATA: 3304 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) 3305 vap->va_size = 0; 3306 else { 3307 /* 3308 * We can drop p->p_lock before grabbing the 3309 * address space lock because p->p_as will not 3310 * change while the process is marked P_PR_LOCK. 3311 */ 3312 mutex_exit(&p->p_lock); 3313 AS_LOCK_ENTER(as, RW_WRITER); 3314 #ifdef _LP64 3315 vap->va_size = iam32bit? 3316 prpdsize32(as) : prpdsize(as); 3317 #else 3318 vap->va_size = prpdsize(as); 3319 #endif 3320 AS_LOCK_EXIT(as); 3321 mutex_enter(&p->p_lock); 3322 } 3323 break; 3324 case PR_OPAGEDATA: 3325 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) 3326 vap->va_size = 0; 3327 else { 3328 mutex_exit(&p->p_lock); 3329 AS_LOCK_ENTER(as, RW_WRITER); 3330 #ifdef _LP64 3331 vap->va_size = iam32bit? 3332 oprpdsize32(as) : oprpdsize(as); 3333 #else 3334 vap->va_size = oprpdsize(as); 3335 #endif 3336 AS_LOCK_EXIT(as); 3337 mutex_enter(&p->p_lock); 3338 } 3339 break; 3340 case PR_WATCH: 3341 vap->va_size = avl_numnodes(&p->p_warea) * 3342 PR_OBJSIZE(prwatch32_t, prwatch_t); 3343 break; 3344 case PR_LWPSTATUS: 3345 vap->va_size = PR_OBJSIZE(lwpstatus32_t, lwpstatus_t); 3346 break; 3347 case PR_LWPSINFO: 3348 vap->va_size = PR_OBJSIZE(lwpsinfo32_t, lwpsinfo_t); 3349 break; 3350 case PR_LWPUSAGE: 3351 vap->va_size = PR_OBJSIZE(prusage32_t, prusage_t); 3352 break; 3353 case PR_XREGS: 3354 if (prhasx(p)) 3355 vap->va_size = prgetprxregsize(p); 3356 else 3357 vap->va_size = 0; 3358 break; 3359 case PR_SPYMASTER: 3360 if (pnp->pr_common->prc_thread != NULL && 3361 pnp->pr_common->prc_thread->t_lwp->lwp_spymaster != NULL) { 3362 vap->va_size = PR_OBJSIZE(psinfo32_t, psinfo_t); 3363 } else { 3364 vap->va_size = 0; 3365 } 3366 break; 3367 #if defined(__sparc) 3368 case PR_GWINDOWS: 3369 { 3370 kthread_t *t; 3371 int n; 3372 3373 /* 3374 * If there is no lwp then just make the size zero. 3375 * This can happen if the lwp exits between the VOP_LOOKUP() 3376 * of the /proc/<pid>/lwp/<lwpid>/gwindows file and the 3377 * VOP_GETATTR() of the resulting vnode. 3378 */ 3379 if ((t = pcp->prc_thread) == NULL) { 3380 vap->va_size = 0; 3381 break; 3382 } 3383 /* 3384 * Drop p->p_lock while touching the stack. 3385 * The P_PR_LOCK flag prevents the lwp from 3386 * disappearing while we do this. 3387 */ 3388 mutex_exit(&p->p_lock); 3389 if ((n = prnwindows(ttolwp(t))) == 0) 3390 vap->va_size = 0; 3391 else 3392 vap->va_size = PR_OBJSIZE(gwindows32_t, gwindows_t) - 3393 (SPARC_MAXREGWINDOW - n) * 3394 PR_OBJSIZE(struct rwindow32, struct rwindow); 3395 mutex_enter(&p->p_lock); 3396 break; 3397 } 3398 case PR_ASRS: 3399 #ifdef _LP64 3400 if (p->p_model == DATAMODEL_LP64) 3401 vap->va_size = sizeof (asrset_t); 3402 else 3403 #endif 3404 vap->va_size = 0; 3405 break; 3406 #endif 3407 case PR_CTL: 3408 case PR_LWPCTL: 3409 default: 3410 vap->va_size = 0; 3411 break; 3412 } 3413 3414 prunlock(pnp); 3415 vap->va_nblocks = (fsblkcnt64_t)btod(vap->va_size); 3416 return (0); 3417 } 3418 3419 static int 3420 praccess(vnode_t *vp, int mode, int flags, cred_t *cr, caller_context_t *ct) 3421 { 3422 prnode_t *pnp = VTOP(vp); 3423 prnodetype_t type = pnp->pr_type; 3424 int vmode; 3425 vtype_t vtype; 3426 proc_t *p; 3427 int error = 0; 3428 vnode_t *rvp; 3429 vnode_t *xvp; 3430 3431 if ((mode & VWRITE) && vn_is_readonly(vp)) 3432 return (EROFS); 3433 3434 switch (type) { 3435 case PR_PROCDIR: 3436 break; 3437 3438 case PR_OBJECT: 3439 case PR_FD: 3440 /* 3441 * Disallow write access to the underlying objects. 3442 * Disallow access to underlying non-regular-file fds. 3443 * Disallow access to fds with other than existing open modes. 3444 */ 3445 rvp = pnp->pr_realvp; 3446 vtype = rvp->v_type; 3447 vmode = pnp->pr_mode; 3448 if ((type == PR_OBJECT && (mode & VWRITE)) || 3449 (type == PR_FD && vtype != VREG && vtype != VDIR) || 3450 (type == PR_FD && (vmode & mode) != mode && 3451 secpolicy_proc_access(cr) != 0)) 3452 return (EACCES); 3453 return (VOP_ACCESS(rvp, mode, flags, cr, ct)); 3454 3455 case PR_PSINFO: /* these files can be read by anyone */ 3456 case PR_LPSINFO: 3457 case PR_LWPSINFO: 3458 case PR_LWPDIR: 3459 case PR_LWPIDDIR: 3460 case PR_USAGE: 3461 case PR_LUSAGE: 3462 case PR_LWPUSAGE: 3463 p = pr_p_lock(pnp); 3464 mutex_exit(&pr_pidlock); 3465 if (p == NULL) 3466 return (ENOENT); 3467 prunlock(pnp); 3468 break; 3469 3470 default: 3471 /* 3472 * Except for the world-readable files above, 3473 * only /proc/pid exists if the process is a zombie. 3474 */ 3475 if ((error = prlock(pnp, 3476 (type == PR_PIDDIR)? ZYES : ZNO)) != 0) 3477 return (error); 3478 p = pnp->pr_common->prc_proc; 3479 if (p != curproc) 3480 error = priv_proc_cred_perm(cr, p, NULL, mode); 3481 3482 if (error != 0 || p == curproc || (p->p_flag & SSYS) || 3483 p->p_as == &kas || (xvp = p->p_exec) == NULL) { 3484 prunlock(pnp); 3485 } else { 3486 /* 3487 * Determine if the process's executable is readable. 3488 * We have to drop p->p_lock before the secpolicy 3489 * and VOP operation. 3490 */ 3491 VN_HOLD(xvp); 3492 prunlock(pnp); 3493 if (secpolicy_proc_access(cr) != 0) 3494 error = VOP_ACCESS(xvp, VREAD, 0, cr, ct); 3495 VN_RELE(xvp); 3496 } 3497 if (error) 3498 return (error); 3499 break; 3500 } 3501 3502 if (type == PR_CURDIR || type == PR_ROOTDIR) { 3503 /* 3504 * Final access check on the underlying directory vnode. 3505 */ 3506 return (VOP_ACCESS(pnp->pr_realvp, mode, flags, cr, ct)); 3507 } 3508 3509 /* 3510 * Visceral revulsion: For compatibility with old /proc, 3511 * allow the /proc/<pid> directory to be opened for writing. 3512 */ 3513 vmode = pnp->pr_mode; 3514 if (type == PR_PIDDIR) 3515 vmode |= VWRITE; 3516 if ((vmode & mode) != mode) 3517 error = secpolicy_proc_access(cr); 3518 return (error); 3519 } 3520 3521 /* 3522 * Array of lookup functions, indexed by /proc file type. 3523 */ 3524 static vnode_t *pr_lookup_notdir(), *pr_lookup_procdir(), *pr_lookup_piddir(), 3525 *pr_lookup_objectdir(), *pr_lookup_lwpdir(), *pr_lookup_lwpiddir(), 3526 *pr_lookup_fddir(), *pr_lookup_fdinfodir(), *pr_lookup_pathdir(), 3527 *pr_lookup_tmpldir(), *pr_lookup_ctdir(); 3528 3529 static vnode_t *(*pr_lookup_function[PR_NFILES])() = { 3530 pr_lookup_procdir, /* /proc */ 3531 pr_lookup_notdir, /* /proc/self */ 3532 pr_lookup_piddir, /* /proc/<pid> */ 3533 pr_lookup_notdir, /* /proc/<pid>/as */ 3534 pr_lookup_notdir, /* /proc/<pid>/ctl */ 3535 pr_lookup_notdir, /* /proc/<pid>/status */ 3536 pr_lookup_notdir, /* /proc/<pid>/lstatus */ 3537 pr_lookup_notdir, /* /proc/<pid>/psinfo */ 3538 pr_lookup_notdir, /* /proc/<pid>/lpsinfo */ 3539 pr_lookup_notdir, /* /proc/<pid>/map */ 3540 pr_lookup_notdir, /* /proc/<pid>/rmap */ 3541 pr_lookup_notdir, /* /proc/<pid>/xmap */ 3542 pr_lookup_notdir, /* /proc/<pid>/cred */ 3543 pr_lookup_notdir, /* /proc/<pid>/sigact */ 3544 pr_lookup_notdir, /* /proc/<pid>/auxv */ 3545 #if defined(__x86) 3546 pr_lookup_notdir, /* /proc/<pid>/ldt */ 3547 #endif 3548 pr_lookup_notdir, /* /proc/<pid>/usage */ 3549 pr_lookup_notdir, /* /proc/<pid>/lusage */ 3550 pr_lookup_notdir, /* /proc/<pid>/pagedata */ 3551 pr_lookup_notdir, /* /proc/<pid>/watch */ 3552 pr_lookup_notdir, /* /proc/<pid>/cwd */ 3553 pr_lookup_notdir, /* /proc/<pid>/root */ 3554 pr_lookup_fddir, /* /proc/<pid>/fd */ 3555 pr_lookup_notdir, /* /proc/<pid>/fd/nn */ 3556 pr_lookup_fdinfodir, /* /proc/<pid>/fdinfo */ 3557 pr_lookup_notdir, /* /proc/<pid>/fdinfo/nn */ 3558 pr_lookup_objectdir, /* /proc/<pid>/object */ 3559 pr_lookup_notdir, /* /proc/<pid>/object/xxx */ 3560 pr_lookup_lwpdir, /* /proc/<pid>/lwp */ 3561 pr_lookup_lwpiddir, /* /proc/<pid>/lwp/<lwpid> */ 3562 pr_lookup_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpctl */ 3563 pr_lookup_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpname */ 3564 pr_lookup_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpstatus */ 3565 pr_lookup_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpsinfo */ 3566 pr_lookup_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpusage */ 3567 pr_lookup_notdir, /* /proc/<pid>/lwp/<lwpid>/xregs */ 3568 pr_lookup_tmpldir, /* /proc/<pid>/lwp/<lwpid>/templates */ 3569 pr_lookup_notdir, /* /proc/<pid>/lwp/<lwpid>/templates/<id> */ 3570 pr_lookup_notdir, /* /proc/<pid>/lwp/<lwpid>/spymaster */ 3571 #if defined(__sparc) 3572 pr_lookup_notdir, /* /proc/<pid>/lwp/<lwpid>/gwindows */ 3573 pr_lookup_notdir, /* /proc/<pid>/lwp/<lwpid>/asrs */ 3574 #endif 3575 pr_lookup_notdir, /* /proc/<pid>/priv */ 3576 pr_lookup_pathdir, /* /proc/<pid>/path */ 3577 pr_lookup_notdir, /* /proc/<pid>/path/xxx */ 3578 pr_lookup_ctdir, /* /proc/<pid>/contracts */ 3579 pr_lookup_notdir, /* /proc/<pid>/contracts/<ctid> */ 3580 pr_lookup_notdir, /* /proc/<pid>/secflags */ 3581 pr_lookup_notdir, /* old process file */ 3582 pr_lookup_notdir, /* old lwp file */ 3583 pr_lookup_notdir, /* old pagedata file */ 3584 }; 3585 3586 static int 3587 prlookup(vnode_t *dp, char *comp, vnode_t **vpp, pathname_t *pathp, 3588 int flags, vnode_t *rdir, cred_t *cr, caller_context_t *ct, 3589 int *direntflags, pathname_t *realpnp) 3590 { 3591 prnode_t *pnp = VTOP(dp); 3592 prnodetype_t type = pnp->pr_type; 3593 int error; 3594 3595 ASSERT(dp->v_type == VDIR); 3596 ASSERT(type < PR_NFILES); 3597 3598 if (type != PR_PROCDIR && strcmp(comp, "..") == 0) { 3599 VN_HOLD(pnp->pr_parent); 3600 *vpp = pnp->pr_parent; 3601 return (0); 3602 } 3603 3604 if (*comp == '\0' || 3605 strcmp(comp, ".") == 0 || strcmp(comp, "..") == 0) { 3606 VN_HOLD(dp); 3607 *vpp = dp; 3608 return (0); 3609 } 3610 3611 switch (type) { 3612 case PR_CURDIR: 3613 case PR_ROOTDIR: 3614 /* restrict lookup permission to owner or root */ 3615 if ((error = praccess(dp, VEXEC, 0, cr, ct)) != 0) 3616 return (error); 3617 /* FALLTHROUGH */ 3618 case PR_FD: 3619 /* 3620 * Performing a VOP_LOOKUP on the underlying vnode and emitting 3621 * the resulting vnode, without encapsulation, as our own is a 3622 * very special case when it comes to the assumptions built 3623 * into VFS. 3624 * 3625 * Since the resulting vnode is highly likely to be at some 3626 * abitrary position in another filesystem, we insist that the 3627 * VTRAVERSE flag is set on the parent. This prevents things 3628 * such as the v_path freshness logic from mistaking the 3629 * resulting vnode as a "real" child of the parent, rather than 3630 * a consequence of this "procfs wormhole". 3631 * 3632 * Failure to establish such protections can lead to 3633 * incorrectly calculated v_paths being set on nodes reached 3634 * through these lookups. 3635 */ 3636 ASSERT((dp->v_flag & VTRAVERSE) != 0); 3637 3638 dp = pnp->pr_realvp; 3639 return (VOP_LOOKUP(dp, comp, vpp, pathp, flags, rdir, cr, ct, 3640 direntflags, realpnp)); 3641 default: 3642 break; 3643 } 3644 3645 if ((type == PR_OBJECTDIR || type == PR_FDDIR || 3646 type == PR_FDINFODIR || type == PR_PATHDIR) && 3647 (error = praccess(dp, VEXEC, 0, cr, ct)) != 0) 3648 return (error); 3649 3650 /* XXX - Do we need to pass ct, direntflags, or realpnp? */ 3651 *vpp = (pr_lookup_function[type](dp, comp)); 3652 3653 return ((*vpp == NULL) ? ENOENT : 0); 3654 } 3655 3656 /* ARGSUSED */ 3657 static int 3658 prcreate(vnode_t *dp, char *comp, vattr_t *vap, vcexcl_t excl, 3659 int mode, vnode_t **vpp, cred_t *cr, int flag, caller_context_t *ct, 3660 vsecattr_t *vsecp) 3661 { 3662 int error; 3663 3664 if ((error = prlookup(dp, comp, vpp, NULL, 0, NULL, cr, 3665 ct, NULL, NULL)) != 0) { 3666 if (error == ENOENT) { 3667 /* One can't O_CREAT nonexistent files in /proc. */ 3668 error = EACCES; 3669 } 3670 return (error); 3671 } 3672 3673 if (excl == EXCL) { 3674 /* Disallow the O_EXCL case */ 3675 error = EEXIST; 3676 } else if ((error = praccess(*vpp, mode, 0, cr, ct)) == 0) { 3677 /* Before proceeding, handle O_TRUNC if necessary. */ 3678 if (vap->va_mask & AT_SIZE) { 3679 vnode_t *vp = *vpp; 3680 3681 if (vp->v_type == VDIR) { 3682 /* Only allow O_TRUNC on files */ 3683 error = EISDIR; 3684 } else if (vp->v_type != VPROC || 3685 VTOP(vp)->pr_type != PR_FD) { 3686 /* 3687 * Disallow for files outside of the 3688 * /proc/<pid>/fd/<n> entries 3689 */ 3690 error = EACCES; 3691 } else { 3692 uint_t mask; 3693 3694 vp = VTOP(vp)->pr_realvp; 3695 mask = vap->va_mask; 3696 vap->va_mask = AT_SIZE; 3697 error = VOP_SETATTR(vp, vap, 0, cr, ct); 3698 vap->va_mask = mask; 3699 } 3700 } 3701 } 3702 3703 if (error) { 3704 VN_RELE(*vpp); 3705 *vpp = NULL; 3706 } 3707 return (error); 3708 } 3709 3710 /* ARGSUSED */ 3711 static vnode_t * 3712 pr_lookup_notdir(vnode_t *dp, char *comp) 3713 { 3714 return (NULL); 3715 } 3716 3717 /* 3718 * Find or construct a process vnode for the given pid. 3719 */ 3720 static vnode_t * 3721 pr_lookup_procdir(vnode_t *dp, char *comp) 3722 { 3723 pid_t pid; 3724 prnode_t *pnp; 3725 prcommon_t *pcp; 3726 vnode_t *vp; 3727 proc_t *p; 3728 int c; 3729 3730 ASSERT(VTOP(dp)->pr_type == PR_PROCDIR); 3731 3732 if (strcmp(comp, "self") == 0) { 3733 pnp = prgetnode(dp, PR_SELF); 3734 return (PTOV(pnp)); 3735 } else { 3736 pid = 0; 3737 while ((c = *comp++) != '\0') { 3738 if (c < '0' || c > '9') 3739 return (NULL); 3740 pid = 10*pid + c - '0'; 3741 if (pid > maxpid) 3742 return (NULL); 3743 } 3744 } 3745 3746 pnp = prgetnode(dp, PR_PIDDIR); 3747 3748 mutex_enter(&pidlock); 3749 if ((p = prfind(pid)) == NULL || p->p_stat == SIDL) { 3750 mutex_exit(&pidlock); 3751 prfreenode(pnp); 3752 return (NULL); 3753 } 3754 ASSERT(p->p_stat != 0); 3755 3756 /* NOTE: we're holding pidlock across the policy call. */ 3757 if (secpolicy_basic_procinfo(CRED(), p, curproc) != 0) { 3758 mutex_exit(&pidlock); 3759 prfreenode(pnp); 3760 return (NULL); 3761 } 3762 3763 mutex_enter(&p->p_lock); 3764 mutex_exit(&pidlock); 3765 3766 /* 3767 * If a process vnode already exists and it is not invalid 3768 * and it was created by the current process and it belongs 3769 * to the same /proc mount point as our parent vnode, then 3770 * just use it and discard the newly-allocated prnode. 3771 */ 3772 for (vp = p->p_trace; vp != NULL; vp = VTOP(vp)->pr_next) { 3773 if (!(VTOP(VTOP(vp)->pr_pidfile)->pr_flags & PR_INVAL) && 3774 VTOP(vp)->pr_owner == curproc && 3775 vp->v_vfsp == dp->v_vfsp) { 3776 ASSERT(!(VTOP(vp)->pr_flags & PR_INVAL)); 3777 VN_HOLD(vp); 3778 prfreenode(pnp); 3779 mutex_exit(&p->p_lock); 3780 return (vp); 3781 } 3782 } 3783 pnp->pr_owner = curproc; 3784 3785 /* 3786 * prgetnode() initialized most of the prnode. 3787 * Finish the job. 3788 */ 3789 pcp = pnp->pr_common; /* the newly-allocated prcommon struct */ 3790 if ((vp = p->p_trace) != NULL) { 3791 /* discard the new prcommon and use the existing prcommon */ 3792 prfreecommon(pcp); 3793 pcp = VTOP(vp)->pr_common; 3794 mutex_enter(&pcp->prc_mutex); 3795 ASSERT(pcp->prc_refcnt > 0); 3796 pcp->prc_refcnt++; 3797 mutex_exit(&pcp->prc_mutex); 3798 pnp->pr_common = pcp; 3799 } else { 3800 /* initialize the new prcommon struct */ 3801 if ((p->p_flag & SSYS) || p->p_as == &kas) 3802 pcp->prc_flags |= PRC_SYS; 3803 if (p->p_stat == SZOMB || (p->p_flag & SEXITING) != 0) 3804 pcp->prc_flags |= PRC_DESTROY; 3805 pcp->prc_proc = p; 3806 pcp->prc_datamodel = p->p_model; 3807 pcp->prc_pid = p->p_pid; 3808 pcp->prc_slot = p->p_slot; 3809 } 3810 pnp->pr_pcommon = pcp; 3811 pnp->pr_parent = dp; 3812 VN_HOLD(dp); 3813 /* 3814 * Link in the old, invalid directory vnode so we 3815 * can later determine the last close of the file. 3816 */ 3817 pnp->pr_next = p->p_trace; 3818 p->p_trace = dp = PTOV(pnp); 3819 3820 /* 3821 * Kludge for old /proc: initialize the PR_PIDFILE as well. 3822 */ 3823 vp = pnp->pr_pidfile; 3824 pnp = VTOP(vp); 3825 pnp->pr_ino = ptoi(pcp->prc_pid); 3826 pnp->pr_common = pcp; 3827 pnp->pr_pcommon = pcp; 3828 pnp->pr_parent = dp; 3829 pnp->pr_next = p->p_plist; 3830 p->p_plist = vp; 3831 3832 mutex_exit(&p->p_lock); 3833 return (dp); 3834 } 3835 3836 static vnode_t * 3837 pr_lookup_piddir(vnode_t *dp, char *comp) 3838 { 3839 prnode_t *dpnp = VTOP(dp); 3840 vnode_t *vp; 3841 prnode_t *pnp; 3842 proc_t *p; 3843 user_t *up; 3844 prdirent_t *dirp; 3845 int i; 3846 enum prnodetype type; 3847 3848 ASSERT(dpnp->pr_type == PR_PIDDIR); 3849 3850 for (i = 0; i < NPIDDIRFILES; i++) { 3851 /* Skip "." and ".." */ 3852 dirp = &piddir[i+2]; 3853 if (strcmp(comp, dirp->d_name) == 0) 3854 break; 3855 } 3856 3857 if (i >= NPIDDIRFILES) 3858 return (NULL); 3859 3860 type = (int)dirp->d_ino; 3861 pnp = prgetnode(dp, type); 3862 3863 p = pr_p_lock(dpnp); 3864 mutex_exit(&pr_pidlock); 3865 if (p == NULL) { 3866 prfreenode(pnp); 3867 return (NULL); 3868 } 3869 if (dpnp->pr_pcommon->prc_flags & PRC_DESTROY) { 3870 switch (type) { 3871 case PR_PSINFO: 3872 case PR_USAGE: 3873 break; 3874 default: 3875 prunlock(dpnp); 3876 prfreenode(pnp); 3877 return (NULL); 3878 } 3879 } 3880 3881 switch (type) { 3882 case PR_CURDIR: 3883 case PR_ROOTDIR: 3884 up = PTOU(p); 3885 vp = (type == PR_CURDIR)? up->u_cdir : 3886 (up->u_rdir? up->u_rdir : rootdir); 3887 3888 if (vp == NULL) { 3889 /* can't happen(?) */ 3890 prunlock(dpnp); 3891 prfreenode(pnp); 3892 return (NULL); 3893 } 3894 /* 3895 * Fill in the prnode so future references will 3896 * be able to find the underlying object's vnode. 3897 */ 3898 VN_HOLD(vp); 3899 pnp->pr_realvp = vp; 3900 PTOV(pnp)->v_flag |= VTRAVERSE; 3901 break; 3902 default: 3903 break; 3904 } 3905 3906 mutex_enter(&dpnp->pr_mutex); 3907 3908 if ((vp = dpnp->pr_files[i]) != NULL && 3909 !(VTOP(vp)->pr_flags & PR_INVAL)) { 3910 VN_HOLD(vp); 3911 mutex_exit(&dpnp->pr_mutex); 3912 prunlock(dpnp); 3913 prfreenode(pnp); 3914 return (vp); 3915 } 3916 3917 /* 3918 * prgetnode() initialized most of the prnode. 3919 * Finish the job. 3920 */ 3921 pnp->pr_common = dpnp->pr_common; 3922 pnp->pr_pcommon = dpnp->pr_pcommon; 3923 pnp->pr_parent = dp; 3924 VN_HOLD(dp); 3925 pnp->pr_index = i; 3926 3927 dpnp->pr_files[i] = vp = PTOV(pnp); 3928 3929 /* 3930 * Link new vnode into list of all /proc vnodes for the process. 3931 */ 3932 if (vp->v_type == VPROC) { 3933 pnp->pr_next = p->p_plist; 3934 p->p_plist = vp; 3935 } 3936 mutex_exit(&dpnp->pr_mutex); 3937 prunlock(dpnp); 3938 return (vp); 3939 } 3940 3941 static vnode_t * 3942 pr_lookup_objectdir(vnode_t *dp, char *comp) 3943 { 3944 prnode_t *dpnp = VTOP(dp); 3945 prnode_t *pnp; 3946 proc_t *p; 3947 struct seg *seg; 3948 struct as *as; 3949 vnode_t *vp; 3950 vattr_t vattr; 3951 3952 ASSERT(dpnp->pr_type == PR_OBJECTDIR); 3953 3954 pnp = prgetnode(dp, PR_OBJECT); 3955 3956 if (prlock(dpnp, ZNO) != 0) { 3957 prfreenode(pnp); 3958 return (NULL); 3959 } 3960 p = dpnp->pr_common->prc_proc; 3961 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) { 3962 prunlock(dpnp); 3963 prfreenode(pnp); 3964 return (NULL); 3965 } 3966 3967 /* 3968 * We drop p_lock before grabbing the address space lock 3969 * in order to avoid a deadlock with the clock thread. 3970 * The process will not disappear and its address space 3971 * will not change because it is marked P_PR_LOCK. 3972 */ 3973 mutex_exit(&p->p_lock); 3974 AS_LOCK_ENTER(as, RW_READER); 3975 if ((seg = AS_SEGFIRST(as)) == NULL) { 3976 vp = NULL; 3977 goto out; 3978 } 3979 if (strcmp(comp, "a.out") == 0) { 3980 vp = p->p_exec; 3981 goto out; 3982 } 3983 do { 3984 /* 3985 * Manufacture a filename for the "object" directory. 3986 */ 3987 vattr.va_mask = AT_FSID|AT_NODEID; 3988 if (seg->s_ops == &segvn_ops && 3989 SEGOP_GETVP(seg, seg->s_base, &vp) == 0 && 3990 vp != NULL && vp->v_type == VREG && 3991 VOP_GETATTR(vp, &vattr, 0, CRED(), NULL) == 0) { 3992 char name[64]; 3993 3994 if (vp == p->p_exec) /* "a.out" */ 3995 continue; 3996 pr_object_name(name, vp, &vattr); 3997 if (strcmp(name, comp) == 0) 3998 goto out; 3999 } 4000 } while ((seg = AS_SEGNEXT(as, seg)) != NULL); 4001 4002 vp = NULL; 4003 out: 4004 if (vp != NULL) { 4005 VN_HOLD(vp); 4006 } 4007 AS_LOCK_EXIT(as); 4008 mutex_enter(&p->p_lock); 4009 prunlock(dpnp); 4010 4011 if (vp == NULL) 4012 prfreenode(pnp); 4013 else { 4014 /* 4015 * Fill in the prnode so future references will 4016 * be able to find the underlying object's vnode. 4017 * Don't link this prnode into the list of all 4018 * prnodes for the process; this is a one-use node. 4019 * Its use is entirely to catch and fail opens for writing. 4020 */ 4021 pnp->pr_realvp = vp; 4022 vp = PTOV(pnp); 4023 } 4024 4025 return (vp); 4026 } 4027 4028 /* 4029 * Find or construct an lwp vnode for the given lwpid. 4030 */ 4031 static vnode_t * 4032 pr_lookup_lwpdir(vnode_t *dp, char *comp) 4033 { 4034 id_t tid; /* same type as t->t_tid */ 4035 int want_agent; 4036 prnode_t *dpnp = VTOP(dp); 4037 prnode_t *pnp; 4038 prcommon_t *pcp; 4039 vnode_t *vp; 4040 proc_t *p; 4041 kthread_t *t; 4042 lwpdir_t *ldp; 4043 lwpent_t *lep; 4044 int tslot; 4045 int c; 4046 4047 ASSERT(dpnp->pr_type == PR_LWPDIR); 4048 4049 tid = 0; 4050 if (strcmp(comp, "agent") == 0) 4051 want_agent = 1; 4052 else { 4053 want_agent = 0; 4054 while ((c = *comp++) != '\0') { 4055 id_t otid; 4056 4057 if (c < '0' || c > '9') 4058 return (NULL); 4059 otid = tid; 4060 tid = 10*tid + c - '0'; 4061 if (tid/10 != otid) /* integer overflow */ 4062 return (NULL); 4063 } 4064 } 4065 4066 pnp = prgetnode(dp, PR_LWPIDDIR); 4067 4068 p = pr_p_lock(dpnp); 4069 mutex_exit(&pr_pidlock); 4070 if (p == NULL) { 4071 prfreenode(pnp); 4072 return (NULL); 4073 } 4074 4075 if (want_agent) { 4076 if ((t = p->p_agenttp) == NULL) 4077 lep = NULL; 4078 else { 4079 tid = t->t_tid; 4080 tslot = t->t_dslot; 4081 lep = p->p_lwpdir[tslot].ld_entry; 4082 } 4083 } else { 4084 if ((ldp = lwp_hash_lookup(p, tid)) == NULL) 4085 lep = NULL; 4086 else { 4087 tslot = (int)(ldp - p->p_lwpdir); 4088 lep = ldp->ld_entry; 4089 } 4090 } 4091 4092 if (lep == NULL) { 4093 prunlock(dpnp); 4094 prfreenode(pnp); 4095 return (NULL); 4096 } 4097 4098 /* 4099 * If an lwp vnode already exists and it is not invalid 4100 * and it was created by the current process and it belongs 4101 * to the same /proc mount point as our parent vnode, then 4102 * just use it and discard the newly-allocated prnode. 4103 */ 4104 for (vp = lep->le_trace; vp != NULL; vp = VTOP(vp)->pr_next) { 4105 if (!(VTOP(vp)->pr_flags & PR_INVAL) && 4106 VTOP(vp)->pr_owner == curproc && 4107 vp->v_vfsp == dp->v_vfsp) { 4108 VN_HOLD(vp); 4109 prunlock(dpnp); 4110 prfreenode(pnp); 4111 return (vp); 4112 } 4113 } 4114 pnp->pr_owner = curproc; 4115 4116 /* 4117 * prgetnode() initialized most of the prnode. 4118 * Finish the job. 4119 */ 4120 pcp = pnp->pr_common; /* the newly-allocated prcommon struct */ 4121 if ((vp = lep->le_trace) != NULL) { 4122 /* discard the new prcommon and use the existing prcommon */ 4123 prfreecommon(pcp); 4124 pcp = VTOP(vp)->pr_common; 4125 mutex_enter(&pcp->prc_mutex); 4126 ASSERT(pcp->prc_refcnt > 0); 4127 pcp->prc_refcnt++; 4128 mutex_exit(&pcp->prc_mutex); 4129 pnp->pr_common = pcp; 4130 } else { 4131 /* initialize the new prcommon struct */ 4132 pcp->prc_flags |= PRC_LWP; 4133 if ((p->p_flag & SSYS) || p->p_as == &kas) 4134 pcp->prc_flags |= PRC_SYS; 4135 if ((t = lep->le_thread) == NULL) 4136 pcp->prc_flags |= PRC_DESTROY; 4137 pcp->prc_proc = p; 4138 pcp->prc_datamodel = dpnp->pr_pcommon->prc_datamodel; 4139 pcp->prc_pid = p->p_pid; 4140 pcp->prc_slot = p->p_slot; 4141 pcp->prc_thread = t; 4142 pcp->prc_tid = tid; 4143 pcp->prc_tslot = tslot; 4144 } 4145 pnp->pr_pcommon = dpnp->pr_pcommon; 4146 pnp->pr_parent = dp; 4147 VN_HOLD(dp); 4148 /* 4149 * Link in the old, invalid directory vnode so we 4150 * can later determine the last close of the file. 4151 */ 4152 pnp->pr_next = lep->le_trace; 4153 lep->le_trace = vp = PTOV(pnp); 4154 prunlock(dpnp); 4155 return (vp); 4156 } 4157 4158 static vnode_t * 4159 pr_lookup_lwpiddir(vnode_t *dp, char *comp) 4160 { 4161 prnode_t *dpnp = VTOP(dp); 4162 vnode_t *vp; 4163 prnode_t *pnp; 4164 proc_t *p; 4165 prdirent_t *dirp; 4166 int i; 4167 enum prnodetype type; 4168 4169 ASSERT(dpnp->pr_type == PR_LWPIDDIR); 4170 4171 for (i = 0; i < NLWPIDDIRFILES; i++) { 4172 /* Skip "." and ".." */ 4173 dirp = &lwpiddir[i+2]; 4174 if (strcmp(comp, dirp->d_name) == 0) 4175 break; 4176 } 4177 4178 if (i >= NLWPIDDIRFILES) 4179 return (NULL); 4180 4181 type = (int)dirp->d_ino; 4182 pnp = prgetnode(dp, type); 4183 4184 p = pr_p_lock(dpnp); 4185 mutex_exit(&pr_pidlock); 4186 if (p == NULL) { 4187 prfreenode(pnp); 4188 return (NULL); 4189 } 4190 if (dpnp->pr_common->prc_flags & PRC_DESTROY) { 4191 /* 4192 * Only the lwpsinfo file is present for zombie lwps. 4193 * Nothing is present if the lwp has been reaped. 4194 */ 4195 if (dpnp->pr_common->prc_tslot == -1 || 4196 type != PR_LWPSINFO) { 4197 prunlock(dpnp); 4198 prfreenode(pnp); 4199 return (NULL); 4200 } 4201 } 4202 4203 #if defined(__sparc) 4204 /* the asrs file exists only for sparc v9 _LP64 processes */ 4205 if (type == PR_ASRS && p->p_model != DATAMODEL_LP64) { 4206 prunlock(dpnp); 4207 prfreenode(pnp); 4208 return (NULL); 4209 } 4210 #endif 4211 4212 mutex_enter(&dpnp->pr_mutex); 4213 4214 if ((vp = dpnp->pr_files[i]) != NULL && 4215 !(VTOP(vp)->pr_flags & PR_INVAL)) { 4216 VN_HOLD(vp); 4217 mutex_exit(&dpnp->pr_mutex); 4218 prunlock(dpnp); 4219 prfreenode(pnp); 4220 return (vp); 4221 } 4222 4223 /* 4224 * prgetnode() initialized most of the prnode. 4225 * Finish the job. 4226 */ 4227 pnp->pr_common = dpnp->pr_common; 4228 pnp->pr_pcommon = dpnp->pr_pcommon; 4229 pnp->pr_parent = dp; 4230 VN_HOLD(dp); 4231 pnp->pr_index = i; 4232 4233 dpnp->pr_files[i] = vp = PTOV(pnp); 4234 4235 /* 4236 * Link new vnode into list of all /proc vnodes for the process. 4237 */ 4238 if (vp->v_type == VPROC) { 4239 pnp->pr_next = p->p_plist; 4240 p->p_plist = vp; 4241 } 4242 mutex_exit(&dpnp->pr_mutex); 4243 prunlock(dpnp); 4244 return (vp); 4245 } 4246 4247 /* 4248 * Lookup one of the process's open files. 4249 */ 4250 static vnode_t * 4251 pr_lookup_fddir(vnode_t *dp, char *comp) 4252 { 4253 prnode_t *dpnp = VTOP(dp); 4254 prnode_t *pnp; 4255 vnode_t *vp = NULL; 4256 proc_t *p; 4257 file_t *fp; 4258 uint_t fd; 4259 int c; 4260 4261 ASSERT(dpnp->pr_type == PR_FDDIR); 4262 4263 fd = 0; 4264 while ((c = *comp++) != '\0') { 4265 int ofd; 4266 if (c < '0' || c > '9') 4267 return (NULL); 4268 ofd = fd; 4269 fd = 10 * fd + c - '0'; 4270 if (fd / 10 != ofd) /* integer overflow */ 4271 return (NULL); 4272 } 4273 4274 pnp = prgetnode(dp, PR_FD); 4275 4276 if (prlock(dpnp, ZNO) != 0) { 4277 prfreenode(pnp); 4278 return (NULL); 4279 } 4280 p = dpnp->pr_common->prc_proc; 4281 if ((p->p_flag & SSYS) || p->p_as == &kas) { 4282 prunlock(dpnp); 4283 prfreenode(pnp); 4284 return (NULL); 4285 } 4286 4287 if ((fp = pr_getf(p, fd, NULL)) != NULL) { 4288 pnp->pr_mode = 07111; 4289 if (fp->f_flag & FREAD) 4290 pnp->pr_mode |= 0444; 4291 if (fp->f_flag & FWRITE) 4292 pnp->pr_mode |= 0222; 4293 vp = fp->f_vnode; 4294 VN_HOLD(vp); 4295 pr_releasef(p, fd); 4296 } 4297 4298 prunlock(dpnp); 4299 4300 if (vp == NULL) { 4301 prfreenode(pnp); 4302 return (NULL); 4303 } 4304 4305 /* 4306 * Fill in the prnode so future references will 4307 * be able to find the underlying object's vnode. 4308 * Don't link this prnode into the list of all 4309 * prnodes for the process; this is a one-use node. 4310 */ 4311 pnp->pr_realvp = vp; 4312 pnp->pr_parent = dp; /* needed for prlookup */ 4313 VN_HOLD(dp); 4314 vp = PTOV(pnp); 4315 if (pnp->pr_realvp->v_type == VDIR) { 4316 vp->v_type = VDIR; 4317 vp->v_flag |= VTRAVERSE; 4318 } 4319 4320 return (vp); 4321 } 4322 4323 static vnode_t * 4324 pr_lookup_fdinfodir(vnode_t *dp, char *comp) 4325 { 4326 prnode_t *dpnp = VTOP(dp); 4327 prnode_t *pnp; 4328 vnode_t *vp = NULL; 4329 proc_t *p; 4330 uint_t fd; 4331 int c; 4332 4333 ASSERT(dpnp->pr_type == PR_FDINFODIR); 4334 4335 fd = 0; 4336 while ((c = *comp++) != '\0') { 4337 int ofd; 4338 if (c < '0' || c > '9') 4339 return (NULL); 4340 ofd = fd; 4341 fd = 10 * fd + c - '0'; 4342 if (fd / 10 != ofd) /* integer overflow */ 4343 return (NULL); 4344 } 4345 4346 pnp = prgetnode(dp, PR_FDINFO); 4347 4348 if (prlock(dpnp, ZNO) != 0) { 4349 prfreenode(pnp); 4350 return (NULL); 4351 } 4352 p = dpnp->pr_common->prc_proc; 4353 if ((p->p_flag & SSYS) || p->p_as == &kas) { 4354 prunlock(dpnp); 4355 prfreenode(pnp); 4356 return (NULL); 4357 } 4358 4359 /* 4360 * Don't link this prnode into the list of all 4361 * prnodes for the process; this is a one-use node. 4362 * Unlike the FDDIR case, the underlying vnode is not stored in 4363 * pnp->pr_realvp. Instead, the fd number is stored in pnp->pr_index 4364 * and used by pr_read_fdinfo() to return information for the right 4365 * file descriptor. 4366 */ 4367 pnp->pr_common = dpnp->pr_common; 4368 pnp->pr_pcommon = dpnp->pr_pcommon; 4369 pnp->pr_parent = dp; 4370 pnp->pr_index = fd; 4371 VN_HOLD(dp); 4372 prunlock(dpnp); 4373 vp = PTOV(pnp); 4374 4375 return (vp); 4376 } 4377 4378 static vnode_t * 4379 pr_lookup_pathdir(vnode_t *dp, char *comp) 4380 { 4381 prnode_t *dpnp = VTOP(dp); 4382 prnode_t *pnp; 4383 vnode_t *vp = NULL; 4384 proc_t *p; 4385 uint_t fd, flags = 0; 4386 int c; 4387 uf_entry_t *ufp; 4388 uf_info_t *fip; 4389 enum { NAME_FD, NAME_OBJECT, NAME_ROOT, NAME_CWD, NAME_UNKNOWN } type; 4390 char *tmp; 4391 int idx; 4392 struct seg *seg; 4393 struct as *as = NULL; 4394 vattr_t vattr; 4395 4396 ASSERT(dpnp->pr_type == PR_PATHDIR); 4397 4398 /* 4399 * First, check if this is a numeric entry, in which case we have a 4400 * file descriptor. 4401 */ 4402 fd = 0; 4403 type = NAME_FD; 4404 tmp = comp; 4405 while ((c = *tmp++) != '\0') { 4406 int ofd; 4407 if (c < '0' || c > '9') { 4408 type = NAME_UNKNOWN; 4409 break; 4410 } 4411 ofd = fd; 4412 fd = 10*fd + c - '0'; 4413 if (fd/10 != ofd) { /* integer overflow */ 4414 type = NAME_UNKNOWN; 4415 break; 4416 } 4417 } 4418 4419 /* 4420 * Next, see if it is one of the special values {root, cwd}. 4421 */ 4422 if (type == NAME_UNKNOWN) { 4423 if (strcmp(comp, "root") == 0) 4424 type = NAME_ROOT; 4425 else if (strcmp(comp, "cwd") == 0) 4426 type = NAME_CWD; 4427 } 4428 4429 /* 4430 * Grab the necessary data from the process 4431 */ 4432 if (prlock(dpnp, ZNO) != 0) 4433 return (NULL); 4434 p = dpnp->pr_common->prc_proc; 4435 4436 fip = P_FINFO(p); 4437 4438 switch (type) { 4439 case NAME_ROOT: 4440 if ((vp = PTOU(p)->u_rdir) == NULL) 4441 vp = p->p_zone->zone_rootvp; 4442 VN_HOLD(vp); 4443 break; 4444 case NAME_CWD: 4445 vp = PTOU(p)->u_cdir; 4446 VN_HOLD(vp); 4447 break; 4448 default: 4449 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) { 4450 prunlock(dpnp); 4451 return (NULL); 4452 } 4453 } 4454 mutex_exit(&p->p_lock); 4455 4456 /* 4457 * Determine if this is an object entry 4458 */ 4459 if (type == NAME_UNKNOWN) { 4460 /* 4461 * Start with the inode index immediately after the number of 4462 * files. 4463 */ 4464 mutex_enter(&fip->fi_lock); 4465 idx = fip->fi_nfiles + 4; 4466 mutex_exit(&fip->fi_lock); 4467 4468 if (strcmp(comp, "a.out") == 0) { 4469 if (p->p_execdir != NULL) { 4470 vp = p->p_execdir; 4471 VN_HOLD(vp); 4472 type = NAME_OBJECT; 4473 flags |= PR_AOUT; 4474 } else { 4475 vp = p->p_exec; 4476 VN_HOLD(vp); 4477 type = NAME_OBJECT; 4478 } 4479 } else { 4480 AS_LOCK_ENTER(as, RW_READER); 4481 if ((seg = AS_SEGFIRST(as)) != NULL) { 4482 do { 4483 /* 4484 * Manufacture a filename for the 4485 * "object" directory. 4486 */ 4487 vattr.va_mask = AT_FSID|AT_NODEID; 4488 if (seg->s_ops == &segvn_ops && 4489 SEGOP_GETVP(seg, seg->s_base, &vp) 4490 == 0 && 4491 vp != NULL && vp->v_type == VREG && 4492 VOP_GETATTR(vp, &vattr, 0, CRED(), 4493 NULL) == 0) { 4494 char name[64]; 4495 4496 if (vp == p->p_exec) 4497 continue; 4498 idx++; 4499 pr_object_name(name, vp, 4500 &vattr); 4501 if (strcmp(name, comp) == 0) 4502 break; 4503 } 4504 } while ((seg = AS_SEGNEXT(as, seg)) != NULL); 4505 } 4506 4507 if (seg == NULL) { 4508 vp = NULL; 4509 } else { 4510 VN_HOLD(vp); 4511 type = NAME_OBJECT; 4512 } 4513 4514 AS_LOCK_EXIT(as); 4515 } 4516 } 4517 4518 4519 switch (type) { 4520 case NAME_FD: 4521 mutex_enter(&fip->fi_lock); 4522 if (fd < fip->fi_nfiles) { 4523 UF_ENTER(ufp, fip, fd); 4524 if (ufp->uf_file != NULL) { 4525 vp = ufp->uf_file->f_vnode; 4526 VN_HOLD(vp); 4527 } 4528 UF_EXIT(ufp); 4529 } 4530 mutex_exit(&fip->fi_lock); 4531 idx = fd + 4; 4532 break; 4533 case NAME_ROOT: 4534 idx = 2; 4535 break; 4536 case NAME_CWD: 4537 idx = 3; 4538 break; 4539 case NAME_OBJECT: 4540 case NAME_UNKNOWN: 4541 /* Nothing to do */ 4542 break; 4543 } 4544 4545 mutex_enter(&p->p_lock); 4546 prunlock(dpnp); 4547 4548 if (vp != NULL) { 4549 pnp = prgetnode(dp, PR_PATH); 4550 4551 pnp->pr_flags |= flags; 4552 pnp->pr_common = dpnp->pr_common; 4553 pnp->pr_pcommon = dpnp->pr_pcommon; 4554 pnp->pr_realvp = vp; 4555 pnp->pr_parent = dp; /* needed for prlookup */ 4556 pnp->pr_ino = pmkino(idx, dpnp->pr_common->prc_slot, PR_PATH); 4557 VN_HOLD(dp); 4558 vp = PTOV(pnp); 4559 vp->v_type = VLNK; 4560 } 4561 4562 return (vp); 4563 } 4564 4565 /* 4566 * Look up one of the process's active templates. 4567 */ 4568 static vnode_t * 4569 pr_lookup_tmpldir(vnode_t *dp, char *comp) 4570 { 4571 prnode_t *dpnp = VTOP(dp); 4572 prnode_t *pnp; 4573 vnode_t *vp = NULL; 4574 proc_t *p; 4575 int i; 4576 4577 ASSERT(dpnp->pr_type == PR_TMPLDIR); 4578 4579 for (i = 0; i < ct_ntypes; i++) 4580 if (strcmp(comp, ct_types[i]->ct_type_name) == 0) 4581 break; 4582 if (i == ct_ntypes) 4583 return (NULL); 4584 4585 pnp = prgetnode(dp, PR_TMPL); 4586 4587 if (prlock(dpnp, ZNO) != 0) { 4588 prfreenode(pnp); 4589 return (NULL); 4590 } 4591 p = dpnp->pr_common->prc_proc; 4592 if ((p->p_flag & SSYS) || p->p_as == &kas || 4593 (dpnp->pr_common->prc_flags & (PRC_DESTROY | PRC_LWP)) != PRC_LWP) { 4594 prunlock(dpnp); 4595 prfreenode(pnp); 4596 return (NULL); 4597 } 4598 if (ttolwp(dpnp->pr_common->prc_thread)->lwp_ct_active[i] != NULL) { 4599 pnp->pr_common = dpnp->pr_common; 4600 pnp->pr_pcommon = dpnp->pr_pcommon; 4601 pnp->pr_parent = dp; 4602 pnp->pr_cttype = i; 4603 VN_HOLD(dp); 4604 vp = PTOV(pnp); 4605 } else { 4606 prfreenode(pnp); 4607 } 4608 prunlock(dpnp); 4609 4610 return (vp); 4611 } 4612 4613 /* 4614 * Look up one of the contracts owned by the process. 4615 */ 4616 static vnode_t * 4617 pr_lookup_ctdir(vnode_t *dp, char *comp) 4618 { 4619 prnode_t *dpnp = VTOP(dp); 4620 prnode_t *pnp; 4621 vnode_t *vp = NULL; 4622 proc_t *p; 4623 id_t id = 0; 4624 contract_t *ct; 4625 int c; 4626 4627 ASSERT(dpnp->pr_type == PR_CTDIR); 4628 4629 while ((c = *comp++) != '\0') { 4630 id_t oid; 4631 if (c < '0' || c > '9') 4632 return (NULL); 4633 oid = id; 4634 id = 10 * id + c - '0'; 4635 if (id / 10 != oid) /* integer overflow */ 4636 return (NULL); 4637 } 4638 4639 /* 4640 * Search all contracts; we'll filter below. 4641 */ 4642 ct = contract_ptr(id, GLOBAL_ZONEUNIQID); 4643 if (ct == NULL) 4644 return (NULL); 4645 4646 pnp = prgetnode(dp, PR_CT); 4647 4648 if (prlock(dpnp, ZNO) != 0) { 4649 prfreenode(pnp); 4650 contract_rele(ct); 4651 return (NULL); 4652 } 4653 p = dpnp->pr_common->prc_proc; 4654 /* 4655 * We only allow lookups of contracts owned by this process, or, 4656 * if we are zsched and this is a zone's procfs, contracts on 4657 * stuff in the zone which are held by processes or contracts 4658 * outside the zone. (see logic in contract_status_common) 4659 */ 4660 if ((ct->ct_owner != p) && 4661 !(p == VTOZONE(dp)->zone_zsched && ct->ct_state < CTS_ORPHAN && 4662 VTOZONE(dp)->zone_uniqid == contract_getzuniqid(ct) && 4663 VTOZONE(dp)->zone_uniqid != GLOBAL_ZONEUNIQID && 4664 ct->ct_czuniqid == GLOBAL_ZONEUNIQID)) { 4665 prunlock(dpnp); 4666 prfreenode(pnp); 4667 contract_rele(ct); 4668 return (NULL); 4669 } 4670 pnp->pr_common = dpnp->pr_common; 4671 pnp->pr_pcommon = dpnp->pr_pcommon; 4672 pnp->pr_contract = ct; 4673 pnp->pr_parent = dp; 4674 pnp->pr_ino = pmkino(id, pnp->pr_common->prc_slot, PR_CT); 4675 VN_HOLD(dp); 4676 prunlock(dpnp); 4677 vp = PTOV(pnp); 4678 4679 return (vp); 4680 } 4681 4682 /* 4683 * Construct an lwp vnode for the old /proc interface. 4684 * We stand on our head to make the /proc plumbing correct. 4685 */ 4686 vnode_t * 4687 prlwpnode(prnode_t *pnp, uint_t tid) 4688 { 4689 char comp[12]; 4690 vnode_t *dp; 4691 vnode_t *vp; 4692 prcommon_t *pcp; 4693 proc_t *p; 4694 4695 /* 4696 * Lookup the /proc/<pid>/lwp/<lwpid> directory vnode. 4697 */ 4698 if (pnp->pr_type == PR_PIDFILE) { 4699 dp = pnp->pr_parent; /* /proc/<pid> */ 4700 VN_HOLD(dp); 4701 vp = pr_lookup_piddir(dp, "lwp"); 4702 VN_RELE(dp); 4703 if ((dp = vp) == NULL) /* /proc/<pid>/lwp */ 4704 return (NULL); 4705 } else if (pnp->pr_type == PR_LWPIDFILE) { 4706 dp = pnp->pr_parent; /* /proc/<pid>/lwp/<lwpid> */ 4707 dp = VTOP(dp)->pr_parent; /* /proc/<pid>/lwp */ 4708 VN_HOLD(dp); 4709 } else { 4710 return (NULL); 4711 } 4712 4713 (void) pr_u32tos(tid, comp, sizeof (comp)); 4714 vp = pr_lookup_lwpdir(dp, comp); 4715 VN_RELE(dp); 4716 if ((dp = vp) == NULL) 4717 return (NULL); 4718 4719 pnp = prgetnode(dp, PR_LWPIDFILE); 4720 vp = PTOV(pnp); 4721 4722 /* 4723 * prgetnode() initialized most of the prnode. 4724 * Finish the job. 4725 */ 4726 pcp = VTOP(dp)->pr_common; 4727 pnp->pr_ino = ptoi(pcp->prc_pid); 4728 pnp->pr_common = pcp; 4729 pnp->pr_pcommon = VTOP(dp)->pr_pcommon; 4730 pnp->pr_parent = dp; 4731 /* 4732 * Link new vnode into list of all /proc vnodes for the process. 4733 */ 4734 p = pr_p_lock(pnp); 4735 mutex_exit(&pr_pidlock); 4736 if (p == NULL) { 4737 VN_RELE(dp); 4738 prfreenode(pnp); 4739 vp = NULL; 4740 } else if (pcp->prc_thread == NULL) { 4741 prunlock(pnp); 4742 VN_RELE(dp); 4743 prfreenode(pnp); 4744 vp = NULL; 4745 } else { 4746 pnp->pr_next = p->p_plist; 4747 p->p_plist = vp; 4748 prunlock(pnp); 4749 } 4750 4751 return (vp); 4752 } 4753 4754 #if defined(DEBUG) 4755 4756 static uint32_t nprnode; 4757 static uint32_t nprcommon; 4758 4759 #define INCREMENT(x) atomic_inc_32(&x); 4760 #define DECREMENT(x) atomic_dec_32(&x); 4761 4762 #else 4763 4764 #define INCREMENT(x) 4765 #define DECREMENT(x) 4766 4767 #endif /* DEBUG */ 4768 4769 /* 4770 * New /proc vnode required; allocate it and fill in most of the fields. 4771 */ 4772 prnode_t * 4773 prgetnode(vnode_t *dp, prnodetype_t type) 4774 { 4775 prnode_t *pnp; 4776 prcommon_t *pcp; 4777 vnode_t *vp; 4778 ulong_t nfiles; 4779 4780 INCREMENT(nprnode); 4781 pnp = kmem_zalloc(sizeof (prnode_t), KM_SLEEP); 4782 4783 mutex_init(&pnp->pr_mutex, NULL, MUTEX_DEFAULT, NULL); 4784 pnp->pr_type = type; 4785 4786 pnp->pr_vnode = vn_alloc(KM_SLEEP); 4787 4788 vp = PTOV(pnp); 4789 vp->v_flag = VNOCACHE|VNOMAP|VNOSWAP|VNOMOUNT; 4790 vn_setops(vp, prvnodeops); 4791 vp->v_vfsp = dp->v_vfsp; 4792 vp->v_type = VPROC; 4793 vp->v_data = (caddr_t)pnp; 4794 4795 switch (type) { 4796 case PR_PIDDIR: 4797 case PR_LWPIDDIR: 4798 /* 4799 * We need a prcommon and a files array for each of these. 4800 */ 4801 INCREMENT(nprcommon); 4802 4803 pcp = kmem_zalloc(sizeof (prcommon_t), KM_SLEEP); 4804 pcp->prc_refcnt = 1; 4805 pnp->pr_common = pcp; 4806 mutex_init(&pcp->prc_mutex, NULL, MUTEX_DEFAULT, NULL); 4807 cv_init(&pcp->prc_wait, NULL, CV_DEFAULT, NULL); 4808 4809 nfiles = (type == PR_PIDDIR)? NPIDDIRFILES : NLWPIDDIRFILES; 4810 pnp->pr_files = 4811 kmem_zalloc(nfiles * sizeof (vnode_t *), KM_SLEEP); 4812 4813 vp->v_type = VDIR; 4814 /* 4815 * Mode should be read-search by all, but we cannot so long 4816 * as we must support compatibility mode with old /proc. 4817 * Make /proc/<pid> be read by owner only, search by all. 4818 * Make /proc/<pid>/lwp/<lwpid> read-search by all. Also, 4819 * set VDIROPEN on /proc/<pid> so it can be opened for writing. 4820 */ 4821 if (type == PR_PIDDIR) { 4822 /* kludge for old /proc interface */ 4823 prnode_t *xpnp = prgetnode(dp, PR_PIDFILE); 4824 pnp->pr_pidfile = PTOV(xpnp); 4825 pnp->pr_mode = 0511; 4826 vp->v_flag |= VDIROPEN; 4827 } else { 4828 pnp->pr_mode = 0555; 4829 } 4830 4831 break; 4832 4833 case PR_CURDIR: 4834 case PR_ROOTDIR: 4835 case PR_FDDIR: 4836 case PR_FDINFODIR: 4837 case PR_OBJECTDIR: 4838 case PR_PATHDIR: 4839 case PR_CTDIR: 4840 case PR_TMPLDIR: 4841 vp->v_type = VDIR; 4842 pnp->pr_mode = 0500; /* read-search by owner only */ 4843 break; 4844 4845 case PR_CT: 4846 vp->v_type = VLNK; 4847 pnp->pr_mode = 0500; /* read-search by owner only */ 4848 break; 4849 4850 case PR_PATH: 4851 case PR_SELF: 4852 vp->v_type = VLNK; 4853 pnp->pr_mode = 0777; 4854 break; 4855 4856 case PR_LWPDIR: 4857 vp->v_type = VDIR; 4858 pnp->pr_mode = 0555; /* read-search by all */ 4859 break; 4860 4861 case PR_AS: 4862 case PR_TMPL: 4863 pnp->pr_mode = 0600; /* read-write by owner only */ 4864 break; 4865 4866 case PR_CTL: 4867 case PR_LWPCTL: 4868 pnp->pr_mode = 0200; /* write-only by owner only */ 4869 break; 4870 4871 case PR_PIDFILE: 4872 case PR_LWPIDFILE: 4873 pnp->pr_mode = 0600; /* read-write by owner only */ 4874 break; 4875 4876 case PR_LWPNAME: 4877 pnp->pr_mode = 0644; /* readable by all + owner can write */ 4878 break; 4879 4880 case PR_PSINFO: 4881 case PR_LPSINFO: 4882 case PR_LWPSINFO: 4883 case PR_USAGE: 4884 case PR_LUSAGE: 4885 case PR_LWPUSAGE: 4886 pnp->pr_mode = 0444; /* read-only by all */ 4887 break; 4888 4889 default: 4890 pnp->pr_mode = 0400; /* read-only by owner only */ 4891 break; 4892 } 4893 vn_exists(vp); 4894 return (pnp); 4895 } 4896 4897 /* 4898 * Free the storage obtained from prgetnode(). 4899 */ 4900 void 4901 prfreenode(prnode_t *pnp) 4902 { 4903 vnode_t *vp; 4904 ulong_t nfiles; 4905 4906 vn_invalid(PTOV(pnp)); 4907 vn_free(PTOV(pnp)); 4908 mutex_destroy(&pnp->pr_mutex); 4909 4910 switch (pnp->pr_type) { 4911 case PR_PIDDIR: 4912 /* kludge for old /proc interface */ 4913 if (pnp->pr_pidfile != NULL) { 4914 prfreenode(VTOP(pnp->pr_pidfile)); 4915 pnp->pr_pidfile = NULL; 4916 } 4917 /* FALLTHROUGH */ 4918 case PR_LWPIDDIR: 4919 /* 4920 * We allocated a prcommon and a files array for each of these. 4921 */ 4922 prfreecommon(pnp->pr_common); 4923 nfiles = (pnp->pr_type == PR_PIDDIR)? 4924 NPIDDIRFILES : NLWPIDDIRFILES; 4925 kmem_free(pnp->pr_files, nfiles * sizeof (vnode_t *)); 4926 break; 4927 default: 4928 break; 4929 } 4930 /* 4931 * If there is an underlying vnode, be sure 4932 * to release it after freeing the prnode. 4933 */ 4934 vp = pnp->pr_realvp; 4935 kmem_free(pnp, sizeof (*pnp)); 4936 DECREMENT(nprnode); 4937 if (vp != NULL) { 4938 VN_RELE(vp); 4939 } 4940 } 4941 4942 /* 4943 * Free a prcommon structure, if the reference count reaches zero. 4944 */ 4945 static void 4946 prfreecommon(prcommon_t *pcp) 4947 { 4948 mutex_enter(&pcp->prc_mutex); 4949 ASSERT(pcp->prc_refcnt > 0); 4950 if (--pcp->prc_refcnt != 0) 4951 mutex_exit(&pcp->prc_mutex); 4952 else { 4953 mutex_exit(&pcp->prc_mutex); 4954 ASSERT(pcp->prc_pollhead.ph_list == NULL); 4955 ASSERT(pcp->prc_refcnt == 0); 4956 ASSERT(pcp->prc_selfopens == 0 && pcp->prc_writers == 0); 4957 mutex_destroy(&pcp->prc_mutex); 4958 cv_destroy(&pcp->prc_wait); 4959 kmem_free(pcp, sizeof (prcommon_t)); 4960 DECREMENT(nprcommon); 4961 } 4962 } 4963 4964 /* 4965 * Array of readdir functions, indexed by /proc file type. 4966 */ 4967 static int pr_readdir_notdir(), pr_readdir_procdir(), pr_readdir_piddir(), 4968 pr_readdir_objectdir(), pr_readdir_lwpdir(), pr_readdir_lwpiddir(), 4969 pr_readdir_fddir(), pr_readdir_fdinfodir(), pr_readdir_pathdir(), 4970 pr_readdir_tmpldir(), pr_readdir_ctdir(); 4971 4972 static int (*pr_readdir_function[PR_NFILES])() = { 4973 pr_readdir_procdir, /* /proc */ 4974 pr_readdir_notdir, /* /proc/self */ 4975 pr_readdir_piddir, /* /proc/<pid> */ 4976 pr_readdir_notdir, /* /proc/<pid>/as */ 4977 pr_readdir_notdir, /* /proc/<pid>/ctl */ 4978 pr_readdir_notdir, /* /proc/<pid>/status */ 4979 pr_readdir_notdir, /* /proc/<pid>/lstatus */ 4980 pr_readdir_notdir, /* /proc/<pid>/psinfo */ 4981 pr_readdir_notdir, /* /proc/<pid>/lpsinfo */ 4982 pr_readdir_notdir, /* /proc/<pid>/map */ 4983 pr_readdir_notdir, /* /proc/<pid>/rmap */ 4984 pr_readdir_notdir, /* /proc/<pid>/xmap */ 4985 pr_readdir_notdir, /* /proc/<pid>/cred */ 4986 pr_readdir_notdir, /* /proc/<pid>/sigact */ 4987 pr_readdir_notdir, /* /proc/<pid>/auxv */ 4988 #if defined(__x86) 4989 pr_readdir_notdir, /* /proc/<pid>/ldt */ 4990 #endif 4991 pr_readdir_notdir, /* /proc/<pid>/usage */ 4992 pr_readdir_notdir, /* /proc/<pid>/lusage */ 4993 pr_readdir_notdir, /* /proc/<pid>/pagedata */ 4994 pr_readdir_notdir, /* /proc/<pid>/watch */ 4995 pr_readdir_notdir, /* /proc/<pid>/cwd */ 4996 pr_readdir_notdir, /* /proc/<pid>/root */ 4997 pr_readdir_fddir, /* /proc/<pid>/fd */ 4998 pr_readdir_notdir, /* /proc/<pid>/fd/nn */ 4999 pr_readdir_fdinfodir, /* /proc/<pid>/fdinfo */ 5000 pr_readdir_notdir, /* /proc/<pid>/fdinfo/nn */ 5001 pr_readdir_objectdir, /* /proc/<pid>/object */ 5002 pr_readdir_notdir, /* /proc/<pid>/object/xxx */ 5003 pr_readdir_lwpdir, /* /proc/<pid>/lwp */ 5004 pr_readdir_lwpiddir, /* /proc/<pid>/lwp/<lwpid> */ 5005 pr_readdir_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpctl */ 5006 pr_readdir_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpname */ 5007 pr_readdir_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpstatus */ 5008 pr_readdir_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpsinfo */ 5009 pr_readdir_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpusage */ 5010 pr_readdir_notdir, /* /proc/<pid>/lwp/<lwpid>/xregs */ 5011 pr_readdir_tmpldir, /* /proc/<pid>/lwp/<lwpid>/templates */ 5012 pr_readdir_notdir, /* /proc/<pid>/lwp/<lwpid>/templates/<id> */ 5013 pr_readdir_notdir, /* /proc/<pid>/lwp/<lwpid>/spymaster */ 5014 #if defined(__sparc) 5015 pr_readdir_notdir, /* /proc/<pid>/lwp/<lwpid>/gwindows */ 5016 pr_readdir_notdir, /* /proc/<pid>/lwp/<lwpid>/asrs */ 5017 #endif 5018 pr_readdir_notdir, /* /proc/<pid>/priv */ 5019 pr_readdir_pathdir, /* /proc/<pid>/path */ 5020 pr_readdir_notdir, /* /proc/<pid>/path/xxx */ 5021 pr_readdir_ctdir, /* /proc/<pid>/contracts */ 5022 pr_readdir_notdir, /* /proc/<pid>/contracts/<ctid> */ 5023 pr_readdir_notdir, /* /proc/<pid>/secflags */ 5024 pr_readdir_notdir, /* old process file */ 5025 pr_readdir_notdir, /* old lwp file */ 5026 pr_readdir_notdir, /* old pagedata file */ 5027 }; 5028 5029 /* ARGSUSED */ 5030 static int 5031 prreaddir(vnode_t *vp, uio_t *uiop, cred_t *cr, int *eofp, 5032 caller_context_t *ct, int flags) 5033 { 5034 prnode_t *pnp = VTOP(vp); 5035 5036 ASSERT(pnp->pr_type < PR_NFILES); 5037 5038 /* XXX - Do we need to pass ct and flags? */ 5039 return (pr_readdir_function[pnp->pr_type](pnp, uiop, eofp)); 5040 } 5041 5042 /* ARGSUSED */ 5043 static int 5044 pr_readdir_notdir(prnode_t *pnp, uio_t *uiop, int *eofp) 5045 { 5046 return (ENOTDIR); 5047 } 5048 5049 /* ARGSUSED */ 5050 static int 5051 pr_readdir_procdir(prnode_t *pnp, uio_t *uiop, int *eofp) 5052 { 5053 zoneid_t zoneid; 5054 gfs_readdir_state_t gstate; 5055 int error, eof = 0; 5056 offset_t n; 5057 5058 ASSERT(pnp->pr_type == PR_PROCDIR); 5059 5060 zoneid = VTOZONE(PTOV(pnp))->zone_id; 5061 5062 if ((error = gfs_readdir_init(&gstate, PNSIZ, PRSDSIZE, uiop, 5063 PRROOTINO, PRROOTINO, 0)) != 0) 5064 return (error); 5065 5066 /* 5067 * Loop until user's request is satisfied or until all processes 5068 * have been examined. 5069 */ 5070 while ((error = gfs_readdir_pred(&gstate, uiop, &n)) == 0) { 5071 uint_t pid; 5072 int pslot; 5073 proc_t *p; 5074 5075 /* 5076 * Find next entry. Skip processes not visible where 5077 * this /proc was mounted. 5078 */ 5079 mutex_enter(&pidlock); 5080 while (n < v.v_proc && 5081 ((p = pid_entry(n)) == NULL || p->p_stat == SIDL || 5082 (zoneid != GLOBAL_ZONEID && p->p_zone->zone_id != zoneid) || 5083 secpolicy_basic_procinfo(CRED(), p, curproc) != 0)) 5084 n++; 5085 5086 /* 5087 * Stop when entire proc table has been examined. 5088 */ 5089 if (n >= v.v_proc) { 5090 mutex_exit(&pidlock); 5091 eof = 1; 5092 break; 5093 } 5094 5095 ASSERT(p->p_stat != 0); 5096 pid = p->p_pid; 5097 pslot = p->p_slot; 5098 mutex_exit(&pidlock); 5099 error = gfs_readdir_emitn(&gstate, uiop, n, 5100 pmkino(0, pslot, PR_PIDDIR), pid); 5101 if (error) 5102 break; 5103 } 5104 5105 return (gfs_readdir_fini(&gstate, error, eofp, eof)); 5106 } 5107 5108 /* ARGSUSED */ 5109 static int 5110 pr_readdir_piddir(prnode_t *pnp, uio_t *uiop, int *eofp) 5111 { 5112 int zombie = ((pnp->pr_pcommon->prc_flags & PRC_DESTROY) != 0); 5113 prdirent_t dirent; 5114 prdirent_t *dirp; 5115 offset_t off; 5116 int error; 5117 5118 ASSERT(pnp->pr_type == PR_PIDDIR); 5119 5120 if (uiop->uio_offset < 0 || 5121 uiop->uio_offset % sizeof (prdirent_t) != 0 || 5122 uiop->uio_resid < sizeof (prdirent_t)) 5123 return (EINVAL); 5124 if (pnp->pr_pcommon->prc_proc == NULL) 5125 return (ENOENT); 5126 if (uiop->uio_offset >= sizeof (piddir)) 5127 goto out; 5128 5129 /* 5130 * Loop until user's request is satisfied, omitting some 5131 * files along the way if the process is a zombie. 5132 */ 5133 for (dirp = &piddir[uiop->uio_offset / sizeof (prdirent_t)]; 5134 uiop->uio_resid >= sizeof (prdirent_t) && 5135 dirp < &piddir[NPIDDIRFILES+2]; 5136 uiop->uio_offset = off + sizeof (prdirent_t), dirp++) { 5137 off = uiop->uio_offset; 5138 if (zombie) { 5139 switch (dirp->d_ino) { 5140 case PR_PIDDIR: 5141 case PR_PROCDIR: 5142 case PR_PSINFO: 5143 case PR_USAGE: 5144 break; 5145 default: 5146 continue; 5147 } 5148 } 5149 bcopy(dirp, &dirent, sizeof (prdirent_t)); 5150 if (dirent.d_ino == PR_PROCDIR) 5151 dirent.d_ino = PRROOTINO; 5152 else 5153 dirent.d_ino = pmkino(0, pnp->pr_pcommon->prc_slot, 5154 dirent.d_ino); 5155 if ((error = uiomove((caddr_t)&dirent, sizeof (prdirent_t), 5156 UIO_READ, uiop)) != 0) 5157 return (error); 5158 } 5159 out: 5160 if (eofp) 5161 *eofp = (uiop->uio_offset >= sizeof (piddir)); 5162 return (0); 5163 } 5164 5165 static void 5166 rebuild_objdir(struct as *as) 5167 { 5168 struct seg *seg; 5169 vnode_t *vp; 5170 vattr_t vattr; 5171 vnode_t **dir; 5172 ulong_t nalloc; 5173 ulong_t nentries; 5174 int i, j; 5175 ulong_t nold, nnew; 5176 5177 ASSERT(AS_WRITE_HELD(as)); 5178 5179 if (as->a_updatedir == 0 && as->a_objectdir != NULL) 5180 return; 5181 as->a_updatedir = 0; 5182 5183 if ((nalloc = avl_numnodes(&as->a_segtree)) == 0 || 5184 (seg = AS_SEGFIRST(as)) == NULL) /* can't happen? */ 5185 return; 5186 5187 /* 5188 * Allocate space for the new object directory. 5189 * (This is usually about two times too many entries.) 5190 */ 5191 nalloc = (nalloc + 0xf) & ~0xf; /* multiple of 16 */ 5192 dir = kmem_zalloc(nalloc * sizeof (vnode_t *), KM_SLEEP); 5193 5194 /* fill in the new directory with desired entries */ 5195 nentries = 0; 5196 do { 5197 vattr.va_mask = AT_FSID|AT_NODEID; 5198 if (seg->s_ops == &segvn_ops && 5199 SEGOP_GETVP(seg, seg->s_base, &vp) == 0 && 5200 vp != NULL && vp->v_type == VREG && 5201 VOP_GETATTR(vp, &vattr, 0, CRED(), NULL) == 0) { 5202 for (i = 0; i < nentries; i++) 5203 if (vp == dir[i]) 5204 break; 5205 if (i == nentries) { 5206 ASSERT(nentries < nalloc); 5207 dir[nentries++] = vp; 5208 } 5209 } 5210 } while ((seg = AS_SEGNEXT(as, seg)) != NULL); 5211 5212 if (as->a_objectdir == NULL) { /* first time */ 5213 as->a_objectdir = dir; 5214 as->a_sizedir = nalloc; 5215 return; 5216 } 5217 5218 /* 5219 * Null out all of the defunct entries in the old directory. 5220 */ 5221 nold = 0; 5222 nnew = nentries; 5223 for (i = 0; i < as->a_sizedir; i++) { 5224 if ((vp = as->a_objectdir[i]) != NULL) { 5225 for (j = 0; j < nentries; j++) { 5226 if (vp == dir[j]) { 5227 dir[j] = NULL; 5228 nnew--; 5229 break; 5230 } 5231 } 5232 if (j == nentries) 5233 as->a_objectdir[i] = NULL; 5234 else 5235 nold++; 5236 } 5237 } 5238 5239 if (nold + nnew > as->a_sizedir) { 5240 /* 5241 * Reallocate the old directory to have enough 5242 * space for the old and new entries combined. 5243 * Round up to the next multiple of 16. 5244 */ 5245 ulong_t newsize = (nold + nnew + 0xf) & ~0xf; 5246 vnode_t **newdir = kmem_zalloc(newsize * sizeof (vnode_t *), 5247 KM_SLEEP); 5248 bcopy(as->a_objectdir, newdir, 5249 as->a_sizedir * sizeof (vnode_t *)); 5250 kmem_free(as->a_objectdir, as->a_sizedir * sizeof (vnode_t *)); 5251 as->a_objectdir = newdir; 5252 as->a_sizedir = newsize; 5253 } 5254 5255 /* 5256 * Move all new entries to the old directory and 5257 * deallocate the space used by the new directory. 5258 */ 5259 if (nnew) { 5260 for (i = 0, j = 0; i < nentries; i++) { 5261 if ((vp = dir[i]) == NULL) 5262 continue; 5263 for (; j < as->a_sizedir; j++) { 5264 if (as->a_objectdir[j] != NULL) 5265 continue; 5266 as->a_objectdir[j++] = vp; 5267 break; 5268 } 5269 } 5270 } 5271 kmem_free(dir, nalloc * sizeof (vnode_t *)); 5272 } 5273 5274 /* 5275 * Return the vnode from a slot in the process's object directory. 5276 * The caller must have locked the process's address space. 5277 * The only caller is below, in pr_readdir_objectdir(). 5278 */ 5279 static vnode_t * 5280 obj_entry(struct as *as, int slot) 5281 { 5282 ASSERT(AS_LOCK_HELD(as)); 5283 if (as->a_objectdir == NULL) 5284 return (NULL); 5285 ASSERT(slot < as->a_sizedir); 5286 return (as->a_objectdir[slot]); 5287 } 5288 5289 /* ARGSUSED */ 5290 static int 5291 pr_readdir_objectdir(prnode_t *pnp, uio_t *uiop, int *eofp) 5292 { 5293 gfs_readdir_state_t gstate; 5294 int error, eof = 0; 5295 offset_t n; 5296 int pslot; 5297 size_t objdirsize; 5298 proc_t *p; 5299 struct as *as; 5300 vnode_t *vp; 5301 5302 ASSERT(pnp->pr_type == PR_OBJECTDIR); 5303 5304 if ((error = prlock(pnp, ZNO)) != 0) 5305 return (error); 5306 p = pnp->pr_common->prc_proc; 5307 pslot = p->p_slot; 5308 5309 /* 5310 * We drop p_lock before grabbing the address space lock 5311 * in order to avoid a deadlock with the clock thread. 5312 * The process will not disappear and its address space 5313 * will not change because it is marked P_PR_LOCK. 5314 */ 5315 mutex_exit(&p->p_lock); 5316 5317 if ((error = gfs_readdir_init(&gstate, 64, PRSDSIZE, uiop, 5318 pmkino(0, pslot, PR_PIDDIR), 5319 pmkino(0, pslot, PR_OBJECTDIR), 0)) != 0) { 5320 mutex_enter(&p->p_lock); 5321 prunlock(pnp); 5322 return (error); 5323 } 5324 5325 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) { 5326 as = NULL; 5327 objdirsize = 0; 5328 } 5329 5330 /* 5331 * Loop until user's request is satisfied or until 5332 * all mapped objects have been examined. Cannot hold 5333 * the address space lock for the following call as 5334 * gfs_readdir_pred() utimately causes a call to uiomove(). 5335 */ 5336 while ((error = gfs_readdir_pred(&gstate, uiop, &n)) == 0) { 5337 vattr_t vattr; 5338 char str[64]; 5339 5340 /* 5341 * Set the correct size of the directory just 5342 * in case the process has changed it's address 5343 * space via mmap/munmap calls. 5344 */ 5345 if (as != NULL) { 5346 AS_LOCK_ENTER(as, RW_WRITER); 5347 if (as->a_updatedir) 5348 rebuild_objdir(as); 5349 objdirsize = as->a_sizedir; 5350 } 5351 5352 /* 5353 * Find next object. 5354 */ 5355 vattr.va_mask = AT_FSID | AT_NODEID; 5356 while (n < objdirsize && (((vp = obj_entry(as, n)) == NULL) || 5357 (VOP_GETATTR(vp, &vattr, 0, CRED(), NULL) 5358 != 0))) { 5359 vattr.va_mask = AT_FSID | AT_NODEID; 5360 n++; 5361 } 5362 5363 if (as != NULL) 5364 AS_LOCK_EXIT(as); 5365 5366 /* 5367 * Stop when all objects have been reported. 5368 */ 5369 if (n >= objdirsize) { 5370 eof = 1; 5371 break; 5372 } 5373 5374 if (vp == p->p_exec) 5375 (void) strcpy(str, "a.out"); 5376 else 5377 pr_object_name(str, vp, &vattr); 5378 5379 error = gfs_readdir_emit(&gstate, uiop, n, vattr.va_nodeid, 5380 str, 0); 5381 5382 if (error) 5383 break; 5384 } 5385 5386 mutex_enter(&p->p_lock); 5387 prunlock(pnp); 5388 5389 return (gfs_readdir_fini(&gstate, error, eofp, eof)); 5390 } 5391 5392 /* ARGSUSED */ 5393 static int 5394 pr_readdir_lwpdir(prnode_t *pnp, uio_t *uiop, int *eofp) 5395 { 5396 gfs_readdir_state_t gstate; 5397 int error, eof = 0; 5398 offset_t tslot; 5399 proc_t *p; 5400 int pslot; 5401 lwpdir_t *lwpdir; 5402 int lwpdirsize; 5403 5404 ASSERT(pnp->pr_type == PR_LWPDIR); 5405 5406 p = pr_p_lock(pnp); 5407 mutex_exit(&pr_pidlock); 5408 if (p == NULL) 5409 return (ENOENT); 5410 ASSERT(p == pnp->pr_common->prc_proc); 5411 pslot = p->p_slot; 5412 lwpdir = p->p_lwpdir; 5413 lwpdirsize = p->p_lwpdir_sz; 5414 5415 /* 5416 * Drop p->p_lock so we can safely do uiomove(). 5417 * The lwp directory will not change because 5418 * we have the process locked with P_PR_LOCK. 5419 */ 5420 mutex_exit(&p->p_lock); 5421 5422 5423 if ((error = gfs_readdir_init(&gstate, PLNSIZ, PRSDSIZE, uiop, 5424 pmkino(0, pslot, PR_PIDDIR), 5425 pmkino(0, pslot, PR_LWPDIR), 0)) != 0) { 5426 mutex_enter(&p->p_lock); 5427 prunlock(pnp); 5428 return (error); 5429 } 5430 5431 /* 5432 * Loop until user's request is satisfied or until all lwps 5433 * have been examined. 5434 */ 5435 while ((error = gfs_readdir_pred(&gstate, uiop, &tslot)) == 0) { 5436 lwpent_t *lep; 5437 uint_t tid; 5438 5439 /* 5440 * Find next LWP. 5441 */ 5442 while (tslot < lwpdirsize && 5443 ((lep = lwpdir[tslot].ld_entry) == NULL)) 5444 tslot++; 5445 /* 5446 * Stop when all lwps have been reported. 5447 */ 5448 if (tslot >= lwpdirsize) { 5449 eof = 1; 5450 break; 5451 } 5452 5453 tid = lep->le_lwpid; 5454 error = gfs_readdir_emitn(&gstate, uiop, tslot, 5455 pmkino(tslot, pslot, PR_LWPIDDIR), tid); 5456 if (error) 5457 break; 5458 } 5459 5460 mutex_enter(&p->p_lock); 5461 prunlock(pnp); 5462 5463 return (gfs_readdir_fini(&gstate, error, eofp, eof)); 5464 } 5465 5466 /* ARGSUSED */ 5467 static int 5468 pr_readdir_lwpiddir(prnode_t *pnp, uio_t *uiop, int *eofp) 5469 { 5470 prcommon_t *pcp = pnp->pr_common; 5471 int zombie = ((pcp->prc_flags & PRC_DESTROY) != 0); 5472 prdirent_t dirent; 5473 prdirent_t *dirp; 5474 offset_t off; 5475 int error; 5476 int pslot; 5477 int tslot; 5478 5479 ASSERT(pnp->pr_type == PR_LWPIDDIR); 5480 5481 if (uiop->uio_offset < 0 || 5482 uiop->uio_offset % sizeof (prdirent_t) != 0 || 5483 uiop->uio_resid < sizeof (prdirent_t)) 5484 return (EINVAL); 5485 if (pcp->prc_proc == NULL || pcp->prc_tslot == -1) 5486 return (ENOENT); 5487 if (uiop->uio_offset >= sizeof (lwpiddir)) 5488 goto out; 5489 5490 /* 5491 * Loop until user's request is satisfied, omitting some files 5492 * along the way if the lwp is a zombie and also depending 5493 * on the data model of the process. 5494 */ 5495 pslot = pcp->prc_slot; 5496 tslot = pcp->prc_tslot; 5497 for (dirp = &lwpiddir[uiop->uio_offset / sizeof (prdirent_t)]; 5498 uiop->uio_resid >= sizeof (prdirent_t) && 5499 dirp < &lwpiddir[NLWPIDDIRFILES+2]; 5500 uiop->uio_offset = off + sizeof (prdirent_t), dirp++) { 5501 off = uiop->uio_offset; 5502 if (zombie) { 5503 switch (dirp->d_ino) { 5504 case PR_LWPIDDIR: 5505 case PR_LWPDIR: 5506 case PR_LWPSINFO: 5507 break; 5508 default: 5509 continue; 5510 } 5511 } 5512 #if defined(__sparc) 5513 /* the asrs file exists only for sparc v9 _LP64 processes */ 5514 if (dirp->d_ino == PR_ASRS && 5515 pcp->prc_datamodel != DATAMODEL_LP64) 5516 continue; 5517 #endif 5518 bcopy(dirp, &dirent, sizeof (prdirent_t)); 5519 if (dirent.d_ino == PR_LWPDIR) 5520 dirent.d_ino = pmkino(0, pslot, dirp->d_ino); 5521 else 5522 dirent.d_ino = pmkino(tslot, pslot, dirp->d_ino); 5523 if ((error = uiomove((caddr_t)&dirent, sizeof (prdirent_t), 5524 UIO_READ, uiop)) != 0) 5525 return (error); 5526 } 5527 out: 5528 if (eofp) 5529 *eofp = (uiop->uio_offset >= sizeof (lwpiddir)); 5530 return (0); 5531 } 5532 5533 /* 5534 * Helper function for reading a directory which lists open file desciptors 5535 */ 5536 static int 5537 pr_readdir_fdlist(prnode_t *pnp, uio_t *uiop, int *eofp, 5538 prnodetype_t dirtype, prnodetype_t entrytype) 5539 { 5540 gfs_readdir_state_t gstate; 5541 int error, eof = 0; 5542 offset_t n; 5543 proc_t *p; 5544 int pslot; 5545 int fddirsize; 5546 uf_info_t *fip; 5547 5548 if ((error = prlock(pnp, ZNO)) != 0) 5549 return (error); 5550 p = pnp->pr_common->prc_proc; 5551 pslot = p->p_slot; 5552 fip = P_FINFO(p); 5553 mutex_exit(&p->p_lock); 5554 5555 if ((error = gfs_readdir_init(&gstate, PLNSIZ, PRSDSIZE, uiop, 5556 pmkino(0, pslot, PR_PIDDIR), pmkino(0, pslot, dirtype), 0)) != 0) { 5557 mutex_enter(&p->p_lock); 5558 prunlock(pnp); 5559 return (error); 5560 } 5561 5562 mutex_enter(&fip->fi_lock); 5563 if ((p->p_flag & SSYS) || p->p_as == &kas) 5564 fddirsize = 0; 5565 else 5566 fddirsize = fip->fi_nfiles; 5567 5568 /* 5569 * Loop until user's request is satisfied or until 5570 * all file descriptors have been examined. 5571 */ 5572 while ((error = gfs_readdir_pred(&gstate, uiop, &n)) == 0) { 5573 /* 5574 * Find next fd. 5575 */ 5576 while (n < fddirsize && fip->fi_list[n].uf_file == NULL) 5577 n++; 5578 /* 5579 * Stop when all fds have been reported. 5580 */ 5581 if (n >= fddirsize) { 5582 eof = 1; 5583 break; 5584 } 5585 5586 error = gfs_readdir_emitn(&gstate, uiop, n, 5587 pmkino(n, pslot, entrytype), n); 5588 if (error) 5589 break; 5590 } 5591 5592 mutex_exit(&fip->fi_lock); 5593 mutex_enter(&p->p_lock); 5594 prunlock(pnp); 5595 5596 return (gfs_readdir_fini(&gstate, error, eofp, eof)); 5597 } 5598 5599 static int 5600 pr_readdir_fddir(prnode_t *pnp, uio_t *uiop, int *eofp) 5601 { 5602 5603 ASSERT(pnp->pr_type == PR_FDDIR); 5604 5605 return (pr_readdir_fdlist(pnp, uiop, eofp, pnp->pr_type, PR_FD)); 5606 } 5607 5608 static int 5609 pr_readdir_fdinfodir(prnode_t *pnp, uio_t *uiop, int *eofp) 5610 { 5611 5612 ASSERT(pnp->pr_type == PR_FDINFODIR); 5613 5614 return (pr_readdir_fdlist(pnp, uiop, eofp, pnp->pr_type, PR_FDINFO)); 5615 } 5616 5617 /* ARGSUSED */ 5618 static int 5619 pr_readdir_pathdir(prnode_t *pnp, uio_t *uiop, int *eofp) 5620 { 5621 longlong_t bp[DIRENT64_RECLEN(64) / sizeof (longlong_t)]; 5622 dirent64_t *dirent = (dirent64_t *)bp; 5623 int reclen; 5624 ssize_t oresid; 5625 offset_t off, idx; 5626 int error = 0; 5627 proc_t *p; 5628 int fd, obj; 5629 int pslot; 5630 int fddirsize; 5631 uf_info_t *fip; 5632 struct as *as = NULL; 5633 size_t objdirsize; 5634 vattr_t vattr; 5635 vnode_t *vp; 5636 5637 ASSERT(pnp->pr_type == PR_PATHDIR); 5638 5639 if (uiop->uio_offset < 0 || 5640 uiop->uio_resid <= 0 || 5641 (uiop->uio_offset % PRSDSIZE) != 0) 5642 return (EINVAL); 5643 oresid = uiop->uio_resid; 5644 bzero(bp, sizeof (bp)); 5645 5646 if ((error = prlock(pnp, ZNO)) != 0) 5647 return (error); 5648 p = pnp->pr_common->prc_proc; 5649 fip = P_FINFO(p); 5650 pslot = p->p_slot; 5651 mutex_exit(&p->p_lock); 5652 5653 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) { 5654 as = NULL; 5655 objdirsize = 0; 5656 } else { 5657 AS_LOCK_ENTER(as, RW_WRITER); 5658 if (as->a_updatedir) 5659 rebuild_objdir(as); 5660 objdirsize = as->a_sizedir; 5661 AS_LOCK_EXIT(as); 5662 as = NULL; 5663 } 5664 5665 mutex_enter(&fip->fi_lock); 5666 if ((p->p_flag & SSYS) || p->p_as == &kas) 5667 fddirsize = 0; 5668 else 5669 fddirsize = fip->fi_nfiles; 5670 5671 for (; uiop->uio_resid > 0; uiop->uio_offset = off + PRSDSIZE) { 5672 /* 5673 * There are 4 special files in the path directory: ".", "..", 5674 * "root", and "cwd". We handle those specially here. 5675 */ 5676 off = uiop->uio_offset; 5677 idx = off / PRSDSIZE; 5678 if (off == 0) { /* "." */ 5679 dirent->d_ino = pmkino(0, pslot, PR_PATHDIR); 5680 dirent->d_name[0] = '.'; 5681 dirent->d_name[1] = '\0'; 5682 reclen = DIRENT64_RECLEN(1); 5683 } else if (idx == 1) { /* ".." */ 5684 dirent->d_ino = pmkino(0, pslot, PR_PIDDIR); 5685 dirent->d_name[0] = '.'; 5686 dirent->d_name[1] = '.'; 5687 dirent->d_name[2] = '\0'; 5688 reclen = DIRENT64_RECLEN(2); 5689 } else if (idx == 2) { /* "root" */ 5690 dirent->d_ino = pmkino(idx, pslot, PR_PATH); 5691 (void) strcpy(dirent->d_name, "root"); 5692 reclen = DIRENT64_RECLEN(4); 5693 } else if (idx == 3) { /* "cwd" */ 5694 dirent->d_ino = pmkino(idx, pslot, PR_PATH); 5695 (void) strcpy(dirent->d_name, "cwd"); 5696 reclen = DIRENT64_RECLEN(3); 5697 } else if (idx < 4 + fddirsize) { 5698 /* 5699 * In this case, we have one of the file descriptors. 5700 */ 5701 fd = idx - 4; 5702 if (fip->fi_list[fd].uf_file == NULL) 5703 continue; 5704 dirent->d_ino = pmkino(idx, pslot, PR_PATH); 5705 (void) pr_u32tos(fd, dirent->d_name, PLNSIZ+1); 5706 reclen = DIRENT64_RECLEN(PLNSIZ); 5707 } else if (idx < 4 + fddirsize + objdirsize) { 5708 if (fip != NULL) { 5709 mutex_exit(&fip->fi_lock); 5710 fip = NULL; 5711 } 5712 5713 /* 5714 * We drop p_lock before grabbing the address space lock 5715 * in order to avoid a deadlock with the clock thread. 5716 * The process will not disappear and its address space 5717 * will not change because it is marked P_PR_LOCK. 5718 */ 5719 if (as == NULL) { 5720 as = p->p_as; 5721 AS_LOCK_ENTER(as, RW_WRITER); 5722 } 5723 5724 if (as->a_updatedir) { 5725 rebuild_objdir(as); 5726 objdirsize = as->a_sizedir; 5727 } 5728 5729 obj = idx - 4 - fddirsize; 5730 if ((vp = obj_entry(as, obj)) == NULL) 5731 continue; 5732 vattr.va_mask = AT_FSID|AT_NODEID; 5733 if (VOP_GETATTR(vp, &vattr, 0, CRED(), NULL) != 0) 5734 continue; 5735 if (vp == p->p_exec) 5736 (void) strcpy(dirent->d_name, "a.out"); 5737 else 5738 pr_object_name(dirent->d_name, vp, &vattr); 5739 dirent->d_ino = pmkino(idx, pslot, PR_PATH); 5740 reclen = DIRENT64_RECLEN(strlen(dirent->d_name)); 5741 } else { 5742 break; 5743 } 5744 5745 dirent->d_off = uiop->uio_offset + PRSDSIZE; 5746 dirent->d_reclen = (ushort_t)reclen; 5747 if (reclen > uiop->uio_resid) { 5748 /* 5749 * Error if no entries have been returned yet. 5750 */ 5751 if (uiop->uio_resid == oresid) 5752 error = EINVAL; 5753 break; 5754 } 5755 /* 5756 * Drop the address space lock to do the uiomove(). 5757 */ 5758 if (as != NULL) 5759 AS_LOCK_EXIT(as); 5760 5761 error = uiomove((caddr_t)dirent, reclen, UIO_READ, uiop); 5762 if (as != NULL) 5763 AS_LOCK_ENTER(as, RW_WRITER); 5764 5765 if (error) 5766 break; 5767 } 5768 5769 if (error == 0 && eofp) 5770 *eofp = (uiop->uio_offset >= (fddirsize + 2) * PRSDSIZE); 5771 5772 if (fip != NULL) 5773 mutex_exit(&fip->fi_lock); 5774 if (as != NULL) 5775 AS_LOCK_EXIT(as); 5776 mutex_enter(&p->p_lock); 5777 prunlock(pnp); 5778 return (error); 5779 } 5780 5781 static int 5782 pr_readdir_tmpldir(prnode_t *pnp, uio_t *uiop, int *eofp) 5783 { 5784 proc_t *p; 5785 int pslot, tslot; 5786 gfs_readdir_state_t gstate; 5787 int error, eof = 0; 5788 offset_t n; 5789 5790 ASSERT(pnp->pr_type == PR_TMPLDIR); 5791 5792 if ((error = prlock(pnp, ZNO)) != 0) 5793 return (error); 5794 p = pnp->pr_common->prc_proc; 5795 pslot = pnp->pr_common->prc_slot; 5796 tslot = pnp->pr_common->prc_tslot; 5797 mutex_exit(&p->p_lock); 5798 5799 if ((error = gfs_readdir_init(&gstate, PRDIRSIZE, PRSDSIZE, uiop, 5800 pmkino(tslot, pslot, PR_LWPDIR), 5801 pmkino(tslot, pslot, PR_TMPLDIR), 0)) != 0) { 5802 mutex_enter(&p->p_lock); 5803 prunlock(pnp); 5804 return (error); 5805 } 5806 5807 while ((error = gfs_readdir_pred(&gstate, uiop, &n)) == 0) { 5808 /* 5809 * Check for an active template. Reading a directory's 5810 * contents is already racy, so we don't bother taking 5811 * any locks. 5812 */ 5813 while (n < ct_ntypes && 5814 pnp->pr_common->prc_thread->t_lwp->lwp_ct_active[n] == NULL) 5815 n++; 5816 /* 5817 * Stop when all types have been reported. 5818 */ 5819 if (n >= ct_ntypes) { 5820 eof = 1; 5821 break; 5822 } 5823 /* 5824 * The pmkino invocation below will need to be updated 5825 * when we create our fifth contract type. 5826 */ 5827 ASSERT(ct_ntypes <= 4); 5828 error = gfs_readdir_emit(&gstate, uiop, n, 5829 pmkino((tslot << 2) | n, pslot, PR_TMPL), 5830 ct_types[n]->ct_type_name, 0); 5831 if (error) 5832 break; 5833 } 5834 5835 mutex_enter(&p->p_lock); 5836 prunlock(pnp); 5837 5838 return (gfs_readdir_fini(&gstate, error, eofp, eof)); 5839 } 5840 5841 static int 5842 pr_readdir_ctdir(prnode_t *pnp, uio_t *uiop, int *eofp) 5843 { 5844 proc_t *p; 5845 int pslot; 5846 gfs_readdir_state_t gstate; 5847 int error, eof = 0; 5848 offset_t n; 5849 uint64_t zid; 5850 5851 ASSERT(pnp->pr_type == PR_CTDIR); 5852 5853 if ((error = prlock(pnp, ZNO)) != 0) 5854 return (error); 5855 p = pnp->pr_common->prc_proc; 5856 pslot = p->p_slot; 5857 mutex_exit(&p->p_lock); 5858 5859 if ((error = gfs_readdir_init(&gstate, PRDIRSIZE, PRSDSIZE, uiop, 5860 pmkino(0, pslot, PR_PIDDIR), pmkino(0, pslot, PR_CTDIR), 0)) != 0) { 5861 mutex_enter(&p->p_lock); 5862 prunlock(pnp); 5863 return (error); 5864 } 5865 5866 zid = VTOZONE(pnp->pr_vnode)->zone_uniqid; 5867 while ((error = gfs_readdir_pred(&gstate, uiop, &n)) == 0) { 5868 id_t next = contract_plookup(p, n, zid); 5869 if (next == -1) { 5870 eof = 1; 5871 break; 5872 } 5873 error = gfs_readdir_emitn(&gstate, uiop, next, 5874 pmkino(next, pslot, PR_CT), next); 5875 if (error) 5876 break; 5877 } 5878 5879 mutex_enter(&p->p_lock); 5880 prunlock(pnp); 5881 5882 return (gfs_readdir_fini(&gstate, error, eofp, eof)); 5883 } 5884 5885 /* ARGSUSED */ 5886 static int 5887 prfsync(vnode_t *vp, int syncflag, cred_t *cr, caller_context_t *ct) 5888 { 5889 return (0); 5890 } 5891 5892 /* 5893 * Utility: remove a /proc vnode from a linked list, threaded through pr_next. 5894 */ 5895 static void 5896 pr_list_unlink(vnode_t *pvp, vnode_t **listp) 5897 { 5898 vnode_t *vp; 5899 prnode_t *pnp; 5900 5901 while ((vp = *listp) != NULL) { 5902 pnp = VTOP(vp); 5903 if (vp == pvp) { 5904 *listp = pnp->pr_next; 5905 pnp->pr_next = NULL; 5906 break; 5907 } 5908 listp = &pnp->pr_next; 5909 } 5910 } 5911 5912 /* ARGSUSED */ 5913 static void 5914 prinactive(vnode_t *vp, cred_t *cr, caller_context_t *ct) 5915 { 5916 prnode_t *pnp = VTOP(vp); 5917 prnodetype_t type = pnp->pr_type; 5918 proc_t *p; 5919 vnode_t *dp; 5920 vnode_t *ovp = NULL; 5921 prnode_t *opnp = NULL; 5922 5923 switch (type) { 5924 case PR_OBJECT: 5925 case PR_FD: 5926 case PR_FDINFO: 5927 case PR_SELF: 5928 case PR_PATH: 5929 /* These are not linked into the usual lists */ 5930 ASSERT(vp->v_count == 1); 5931 if ((dp = pnp->pr_parent) != NULL) 5932 VN_RELE(dp); 5933 prfreenode(pnp); 5934 return; 5935 default: 5936 break; 5937 } 5938 5939 mutex_enter(&pr_pidlock); 5940 if (pnp->pr_pcommon == NULL) 5941 p = NULL; 5942 else if ((p = pnp->pr_pcommon->prc_proc) != NULL) 5943 mutex_enter(&p->p_lock); 5944 mutex_enter(&vp->v_lock); 5945 5946 if (type == PR_PROCDIR || vp->v_count > 1) { 5947 VN_RELE_LOCKED(vp); 5948 mutex_exit(&vp->v_lock); 5949 if (p != NULL) 5950 mutex_exit(&p->p_lock); 5951 mutex_exit(&pr_pidlock); 5952 return; 5953 } 5954 5955 if ((dp = pnp->pr_parent) != NULL) { 5956 prnode_t *dpnp; 5957 5958 switch (type) { 5959 case PR_PIDFILE: 5960 case PR_LWPIDFILE: 5961 case PR_OPAGEDATA: 5962 break; 5963 default: 5964 dpnp = VTOP(dp); 5965 mutex_enter(&dpnp->pr_mutex); 5966 if (dpnp->pr_files != NULL && 5967 dpnp->pr_files[pnp->pr_index] == vp) 5968 dpnp->pr_files[pnp->pr_index] = NULL; 5969 mutex_exit(&dpnp->pr_mutex); 5970 break; 5971 } 5972 pnp->pr_parent = NULL; 5973 } 5974 5975 ASSERT(vp->v_count == 1); 5976 5977 /* 5978 * If we allocated an old /proc/pid node, free it too. 5979 */ 5980 if (pnp->pr_pidfile != NULL) { 5981 ASSERT(type == PR_PIDDIR); 5982 ovp = pnp->pr_pidfile; 5983 opnp = VTOP(ovp); 5984 ASSERT(opnp->pr_type == PR_PIDFILE); 5985 pnp->pr_pidfile = NULL; 5986 } 5987 5988 mutex_exit(&pr_pidlock); 5989 5990 if (p != NULL) { 5991 /* 5992 * Remove the vnodes from the lists of 5993 * /proc vnodes for the process. 5994 */ 5995 int slot; 5996 5997 switch (type) { 5998 case PR_PIDDIR: 5999 pr_list_unlink(vp, &p->p_trace); 6000 break; 6001 case PR_LWPIDDIR: 6002 if ((slot = pnp->pr_common->prc_tslot) != -1) { 6003 lwpent_t *lep = p->p_lwpdir[slot].ld_entry; 6004 pr_list_unlink(vp, &lep->le_trace); 6005 } 6006 break; 6007 default: 6008 pr_list_unlink(vp, &p->p_plist); 6009 break; 6010 } 6011 if (ovp != NULL) 6012 pr_list_unlink(ovp, &p->p_plist); 6013 mutex_exit(&p->p_lock); 6014 } 6015 6016 mutex_exit(&vp->v_lock); 6017 6018 if (type == PR_CT && pnp->pr_contract != NULL) { 6019 contract_rele(pnp->pr_contract); 6020 pnp->pr_contract = NULL; 6021 } 6022 6023 if (opnp != NULL) 6024 prfreenode(opnp); 6025 prfreenode(pnp); 6026 if (dp != NULL) { 6027 VN_RELE(dp); 6028 } 6029 } 6030 6031 /* ARGSUSED */ 6032 static int 6033 prseek(vnode_t *vp, offset_t ooff, offset_t *noffp, caller_context_t *ct) 6034 { 6035 return (0); 6036 } 6037 6038 /* 6039 * We use the p_execdir member of proc_t to expand the %d token in core file 6040 * paths (the directory path for the executable that dumped core; see 6041 * coreadm(1M) for details). We'd like gcore(1) to be able to expand %d in 6042 * the same way as core dumping from the kernel, but there's no convenient 6043 * and comprehensible way to export the path name for p_execdir. To solve 6044 * this, we try to find the actual path to the executable that was used. In 6045 * pr_lookup_pathdir(), we mark the a.out path name vnode with the PR_AOUT 6046 * flag, and use that here to indicate that more work is needed beyond the 6047 * call to vnodetopath(). 6048 */ 6049 static int 6050 prreadlink_lookup(prnode_t *pnp, char *buf, size_t size, cred_t *cr) 6051 { 6052 proc_t *p; 6053 vnode_t *vp, *execvp, *vrootp; 6054 int ret; 6055 size_t len; 6056 dirent64_t *dp; 6057 size_t dlen = DIRENT64_RECLEN(MAXPATHLEN); 6058 char *dbuf; 6059 6060 p = curproc; 6061 mutex_enter(&p->p_lock); 6062 if ((vrootp = PTOU(p)->u_rdir) == NULL) 6063 vrootp = rootdir; 6064 VN_HOLD(vrootp); 6065 mutex_exit(&p->p_lock); 6066 6067 ret = vnodetopath(vrootp, pnp->pr_realvp, buf, size, cr); 6068 6069 /* 6070 * If PR_AOUT isn't set, then we looked up the path for the vnode; 6071 * otherwise, we looked up the path for (what we believe to be) the 6072 * containing directory. 6073 */ 6074 if ((pnp->pr_flags & PR_AOUT) == 0) { 6075 VN_RELE(vrootp); 6076 return (ret); 6077 } 6078 6079 /* 6080 * Fail if there's a problem locking the process. This will only 6081 * occur if the process is changing so the information we would 6082 * report would already be invalid. 6083 */ 6084 if (prlock(pnp, ZNO) != 0) { 6085 VN_RELE(vrootp); 6086 return (EIO); 6087 } 6088 6089 p = pnp->pr_common->prc_proc; 6090 mutex_exit(&p->p_lock); 6091 6092 execvp = p->p_exec; 6093 VN_HOLD(execvp); 6094 6095 /* 6096 * If our initial lookup of the directory failed, fall back to 6097 * the path name information for p_exec. 6098 */ 6099 if (ret != 0) { 6100 mutex_enter(&p->p_lock); 6101 prunlock(pnp); 6102 ret = vnodetopath(vrootp, execvp, buf, size, cr); 6103 VN_RELE(execvp); 6104 VN_RELE(vrootp); 6105 return (ret); 6106 } 6107 6108 len = strlen(buf); 6109 6110 /* 6111 * We use u_comm as a guess for the last component of the full 6112 * executable path name. If there isn't going to be enough space 6113 * we fall back to using the p_exec so that we can have _an_ 6114 * answer even if it's not perfect. 6115 */ 6116 if (strlen(PTOU(p)->u_comm) + len + 1 < size) { 6117 buf[len] = '/'; 6118 (void) strcpy(buf + len + 1, PTOU(p)->u_comm); 6119 mutex_enter(&p->p_lock); 6120 prunlock(pnp); 6121 6122 /* 6123 * Do a forward lookup of our u_comm guess. 6124 */ 6125 if (lookupnameat(buf + len + 1, UIO_SYSSPACE, FOLLOW, NULLVPP, 6126 &vp, pnp->pr_realvp) == 0) { 6127 if (vn_compare(vp, execvp)) { 6128 VN_RELE(vp); 6129 VN_RELE(execvp); 6130 VN_RELE(vrootp); 6131 return (0); 6132 } 6133 6134 VN_RELE(vp); 6135 } 6136 } else { 6137 mutex_enter(&p->p_lock); 6138 prunlock(pnp); 6139 } 6140 6141 dbuf = kmem_alloc(dlen, KM_SLEEP); 6142 6143 /* 6144 * Try to find a matching vnode by iterating through the directory's 6145 * entries. If that fails, fall back to the path information for 6146 * p_exec. 6147 */ 6148 if ((ret = dirfindvp(vrootp, pnp->pr_realvp, execvp, cr, dbuf, 6149 dlen, &dp)) == 0 && strlen(dp->d_name) + len + 1 < size) { 6150 buf[len] = '/'; 6151 (void) strcpy(buf + len + 1, dp->d_name); 6152 } else { 6153 ret = vnodetopath(vrootp, execvp, buf, size, cr); 6154 } 6155 6156 kmem_free(dbuf, dlen); 6157 VN_RELE(execvp); 6158 VN_RELE(vrootp); 6159 6160 return (ret); 6161 } 6162 6163 /* ARGSUSED */ 6164 static int 6165 prreadlink(vnode_t *vp, uio_t *uiop, cred_t *cr, caller_context_t *ctp) 6166 { 6167 prnode_t *pnp = VTOP(vp); 6168 char *buf; 6169 int ret = EINVAL; 6170 char idbuf[16]; 6171 int length, rlength; 6172 contract_t *ct; 6173 6174 switch (pnp->pr_type) { 6175 case PR_SELF: 6176 (void) snprintf(idbuf, sizeof (idbuf), "%d", curproc->p_pid); 6177 ret = uiomove(idbuf, strlen(idbuf), UIO_READ, uiop); 6178 break; 6179 case PR_OBJECT: 6180 case PR_FD: 6181 case PR_CURDIR: 6182 case PR_ROOTDIR: 6183 if (pnp->pr_realvp->v_type == VDIR) 6184 ret = 0; 6185 break; 6186 case PR_PATH: 6187 buf = kmem_alloc(MAXPATHLEN, KM_SLEEP); 6188 6189 if ((ret = prreadlink_lookup(pnp, buf, MAXPATHLEN, cr)) == 0) 6190 ret = uiomove(buf, strlen(buf), UIO_READ, uiop); 6191 6192 kmem_free(buf, MAXPATHLEN); 6193 break; 6194 case PR_CT: 6195 ASSERT(pnp->pr_contract != NULL); 6196 ct = pnp->pr_contract; 6197 length = sizeof (CTFS_ROOT "//") + sizeof (idbuf) + 6198 strlen(ct->ct_type->ct_type_name); 6199 buf = kmem_alloc(length, KM_SLEEP); 6200 rlength = snprintf(buf, length, CTFS_ROOT "/%s/%d", 6201 ct->ct_type->ct_type_name, ct->ct_id); 6202 ASSERT(rlength < length); 6203 ret = uiomove(buf, rlength, UIO_READ, uiop); 6204 kmem_free(buf, length); 6205 break; 6206 default: 6207 break; 6208 } 6209 6210 return (ret); 6211 } 6212 6213 /*ARGSUSED2*/ 6214 static int 6215 prcmp(vnode_t *vp1, vnode_t *vp2, caller_context_t *ct) 6216 { 6217 prnode_t *pp1, *pp2; 6218 6219 if (vp1 == vp2) 6220 return (1); 6221 6222 if (!vn_matchops(vp1, prvnodeops) || !vn_matchops(vp2, prvnodeops)) 6223 return (0); 6224 6225 pp1 = VTOP(vp1); 6226 pp2 = VTOP(vp2); 6227 6228 if (pp1->pr_type != pp2->pr_type) 6229 return (0); 6230 if (pp1->pr_type == PR_PROCDIR) 6231 return (1); 6232 if (pp1->pr_ino || pp2->pr_ino) 6233 return (pp2->pr_ino == pp1->pr_ino); 6234 6235 if (pp1->pr_common == NULL || pp2->pr_common == NULL) 6236 return (0); 6237 6238 return (pp1->pr_common->prc_slot == pp2->pr_common->prc_slot && 6239 pp1->pr_common->prc_tslot == pp2->pr_common->prc_tslot); 6240 } 6241 6242 static int 6243 prrealvp(vnode_t *vp, vnode_t **vpp, caller_context_t *ct) 6244 { 6245 vnode_t *rvp; 6246 6247 if ((rvp = VTOP(vp)->pr_realvp) != NULL) { 6248 vp = rvp; 6249 if (VOP_REALVP(vp, &rvp, ct) == 0) 6250 vp = rvp; 6251 } 6252 6253 *vpp = vp; 6254 return (0); 6255 } 6256 6257 /* 6258 * Return the answer requested to poll(). 6259 * POLLIN, POLLRDNORM, and POLLOUT are recognized as in fs_poll(). 6260 * In addition, these have special meaning for /proc files: 6261 * POLLPRI process or lwp stopped on an event of interest 6262 * POLLERR /proc file descriptor is invalid 6263 * POLLHUP process or lwp has terminated 6264 */ 6265 /*ARGSUSED5*/ 6266 static int 6267 prpoll(vnode_t *vp, short events, int anyyet, short *reventsp, 6268 pollhead_t **phpp, caller_context_t *ct) 6269 { 6270 prnode_t *pnp = VTOP(vp); 6271 prcommon_t *pcp = pnp->pr_common; 6272 pollhead_t *php = &pcp->prc_pollhead; 6273 proc_t *p; 6274 short revents; 6275 int error; 6276 int lockstate; 6277 6278 ASSERT(pnp->pr_type < PR_NFILES); 6279 6280 /* 6281 * Support for old /proc interface. 6282 */ 6283 if (pnp->pr_pidfile != NULL) { 6284 vp = pnp->pr_pidfile; 6285 pnp = VTOP(vp); 6286 ASSERT(pnp->pr_type == PR_PIDFILE); 6287 ASSERT(pnp->pr_common == pcp); 6288 } 6289 6290 *reventsp = revents = 0; 6291 *phpp = (pollhead_t *)NULL; 6292 6293 if (vp->v_type == VDIR) { 6294 *reventsp |= POLLNVAL; 6295 return (0); 6296 } 6297 6298 /* avoid deadlock with prnotify() */ 6299 if (pollunlock(&lockstate) != 0) { 6300 *reventsp = POLLNVAL; 6301 return (0); 6302 } 6303 6304 if ((error = prlock(pnp, ZNO)) != 0) { 6305 pollrelock(lockstate); 6306 switch (error) { 6307 case ENOENT: /* process or lwp died */ 6308 *reventsp = POLLHUP; 6309 error = 0; 6310 break; 6311 case EAGAIN: /* invalidated */ 6312 *reventsp = POLLERR; 6313 error = 0; 6314 break; 6315 } 6316 return (error); 6317 } 6318 6319 /* 6320 * We have the process marked locked (P_PR_LOCK) and we are holding 6321 * its p->p_lock. We want to unmark the process but retain 6322 * exclusive control w.r.t. other /proc controlling processes 6323 * before reacquiring the polling locks. 6324 * 6325 * prunmark() does this for us. It unmarks the process 6326 * but retains p->p_lock so we still have exclusive control. 6327 * We will drop p->p_lock at the end to relinquish control. 6328 * 6329 * We cannot call prunlock() at the end to relinquish control 6330 * because prunlock(), like prunmark(), may drop and reacquire 6331 * p->p_lock and that would lead to a lock order violation 6332 * w.r.t. the polling locks we are about to reacquire. 6333 */ 6334 p = pcp->prc_proc; 6335 ASSERT(p != NULL); 6336 prunmark(p); 6337 6338 pollrelock(lockstate); /* reacquire dropped poll locks */ 6339 6340 if ((p->p_flag & SSYS) || p->p_as == &kas) 6341 revents = POLLNVAL; 6342 else { 6343 short ev; 6344 6345 if ((ev = (events & (POLLIN|POLLRDNORM))) != 0) 6346 revents |= ev; 6347 /* 6348 * POLLWRNORM (same as POLLOUT) really should not be 6349 * used to indicate that the process or lwp stopped. 6350 * However, USL chose to use POLLWRNORM rather than 6351 * POLLPRI to indicate this, so we just accept either 6352 * requested event to indicate stopped. (grr...) 6353 */ 6354 if ((ev = (events & (POLLPRI|POLLOUT|POLLWRNORM))) != 0) { 6355 kthread_t *t; 6356 6357 if (pcp->prc_flags & PRC_LWP) { 6358 t = pcp->prc_thread; 6359 ASSERT(t != NULL); 6360 thread_lock(t); 6361 } else { 6362 t = prchoose(p); /* returns locked t */ 6363 ASSERT(t != NULL); 6364 } 6365 6366 if (ISTOPPED(t) || VSTOPPED(t)) 6367 revents |= ev; 6368 thread_unlock(t); 6369 } 6370 } 6371 6372 *reventsp = revents; 6373 if ((!anyyet && revents == 0) || (events & POLLET)) { 6374 /* 6375 * Arrange to wake up the polling lwp when 6376 * the target process/lwp stops or terminates 6377 * or when the file descriptor becomes invalid. 6378 */ 6379 pcp->prc_flags |= PRC_POLL; 6380 *phpp = php; 6381 } 6382 mutex_exit(&p->p_lock); 6383 return (0); 6384 } 6385 6386 /* in prioctl.c */ 6387 extern int prioctl(vnode_t *, int, intptr_t, int, cred_t *, int *, 6388 caller_context_t *); 6389 6390 /* 6391 * /proc vnode operations vector 6392 */ 6393 const fs_operation_def_t pr_vnodeops_template[] = { 6394 VOPNAME_OPEN, { .vop_open = propen }, 6395 VOPNAME_CLOSE, { .vop_close = prclose }, 6396 VOPNAME_READ, { .vop_read = prread }, 6397 VOPNAME_WRITE, { .vop_write = prwrite }, 6398 VOPNAME_IOCTL, { .vop_ioctl = prioctl }, 6399 VOPNAME_GETATTR, { .vop_getattr = prgetattr }, 6400 VOPNAME_ACCESS, { .vop_access = praccess }, 6401 VOPNAME_LOOKUP, { .vop_lookup = prlookup }, 6402 VOPNAME_CREATE, { .vop_create = prcreate }, 6403 VOPNAME_READDIR, { .vop_readdir = prreaddir }, 6404 VOPNAME_READLINK, { .vop_readlink = prreadlink }, 6405 VOPNAME_FSYNC, { .vop_fsync = prfsync }, 6406 VOPNAME_INACTIVE, { .vop_inactive = prinactive }, 6407 VOPNAME_SEEK, { .vop_seek = prseek }, 6408 VOPNAME_CMP, { .vop_cmp = prcmp }, 6409 VOPNAME_FRLOCK, { .error = fs_error }, 6410 VOPNAME_REALVP, { .vop_realvp = prrealvp }, 6411 VOPNAME_POLL, { .vop_poll = prpoll }, 6412 VOPNAME_DISPOSE, { .error = fs_error }, 6413 VOPNAME_SHRLOCK, { .error = fs_error }, 6414 NULL, NULL 6415 }; 6416