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