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