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