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