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