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