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