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