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