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