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