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