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