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