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