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