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