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