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