Print this page
8158 Want named threads API
9857 proc manpages should have LIBRARY section


   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright (c) 2017, Joyent, Inc.
  25  * Copyright (c) 2017 by Delphix. All rights reserved.
  26  */
  27 
  28 /*      Copyright (c) 1984,      1986, 1987, 1988, 1989 AT&T        */
  29 /*        All Rights Reserved   */
  30 
  31 #include <sys/types.h>
  32 #include <sys/param.h>
  33 #include <sys/time.h>
  34 #include <sys/cred.h>
  35 #include <sys/policy.h>
  36 #include <sys/debug.h>
  37 #include <sys/dirent.h>
  38 #include <sys/errno.h>
  39 #include <sys/file.h>
  40 #include <sys/inline.h>
  41 #include <sys/kmem.h>
  42 #include <sys/pathname.h>
  43 #include <sys/proc.h>
  44 #include <sys/brand.h>


  47 #include <sys/sysmacros.h>
  48 #include <sys/systm.h>
  49 #include <sys/zone.h>
  50 #include <sys/uio.h>
  51 #include <sys/var.h>
  52 #include <sys/mode.h>
  53 #include <sys/poll.h>
  54 #include <sys/user.h>
  55 #include <sys/vfs.h>
  56 #include <sys/vfs_opreg.h>
  57 #include <sys/gfs.h>
  58 #include <sys/vnode.h>
  59 #include <sys/fault.h>
  60 #include <sys/syscall.h>
  61 #include <sys/procfs.h>
  62 #include <sys/atomic.h>
  63 #include <sys/cmn_err.h>
  64 #include <sys/contract_impl.h>
  65 #include <sys/ctfs.h>
  66 #include <sys/avl.h>

  67 #include <fs/fs_subr.h>
  68 #include <vm/rm.h>
  69 #include <vm/as.h>
  70 #include <vm/seg.h>
  71 #include <vm/seg_vn.h>
  72 #include <vm/hat.h>
  73 #include <fs/proc/prdata.h>
  74 #if defined(__sparc)
  75 #include <sys/regset.h>
  76 #endif
  77 #if defined(__x86)
  78 #include <sys/sysi86.h>
  79 #endif
  80 
  81 /*
  82  * Created by prinit.
  83  */
  84 vnodeops_t *prvnodeops;
  85 
  86 /*


 166         { PR_SECFLAGS,  27 * sizeof (prdirent_t), sizeof (prdirent_t),
 167                 "secflags" },
 168 #if defined(__x86)
 169         { PR_LDT,       28 * sizeof (prdirent_t), sizeof (prdirent_t),
 170                 "ldt" },
 171 #endif
 172 };
 173 
 174 #define NPIDDIRFILES    (sizeof (piddir) / sizeof (piddir[0]) - 2)
 175 
 176 /*
 177  * Contents of a /proc/<pid>/lwp/<lwpid> directory.
 178  */
 179 static prdirent_t lwpiddir[] = {
 180         { PR_LWPIDDIR,   1 * sizeof (prdirent_t), sizeof (prdirent_t),
 181                 "." },
 182         { PR_LWPDIR,     2 * sizeof (prdirent_t), sizeof (prdirent_t),
 183                 ".." },
 184         { PR_LWPCTL,     3 * sizeof (prdirent_t), sizeof (prdirent_t),
 185                 "lwpctl" },
 186         { PR_LWPSTATUS,  4 * sizeof (prdirent_t), sizeof (prdirent_t),


 187                 "lwpstatus" },
 188         { PR_LWPSINFO,   5 * sizeof (prdirent_t), sizeof (prdirent_t),
 189                 "lwpsinfo" },
 190         { PR_LWPUSAGE,   6 * sizeof (prdirent_t), sizeof (prdirent_t),
 191                 "lwpusage" },
 192         { PR_XREGS,      7 * sizeof (prdirent_t), sizeof (prdirent_t),
 193                 "xregs" },
 194         { PR_TMPLDIR,    8 * sizeof (prdirent_t), sizeof (prdirent_t),
 195                 "templates" },
 196         { PR_SPYMASTER,  9 * sizeof (prdirent_t), sizeof (prdirent_t),
 197                 "spymaster" },
 198 #if defined(__sparc)
 199         { PR_GWINDOWS,  10 * sizeof (prdirent_t), sizeof (prdirent_t),
 200                 "gwindows" },
 201         { PR_ASRS,      11 * sizeof (prdirent_t), sizeof (prdirent_t),
 202                 "asrs" },
 203 #endif
 204 };
 205 
 206 #define NLWPIDDIRFILES  (sizeof (lwpiddir) / sizeof (lwpiddir[0]) - 2)
 207 
 208 /*
 209  * Span of entries in the array files (lstatus, lpsinfo, lusage).
 210  * We make the span larger than the size of the structure on purpose,
 211  * to make sure that programs cannot use the structure size by mistake.
 212  * Align _ILP32 structures at 8 bytes, _LP64 structures at 16 bytes.
 213  */
 214 #ifdef _LP64
 215 #define LSPAN(type)     (round16(sizeof (type)) + 16)
 216 #define LSPAN32(type)   (round8(sizeof (type)) + 8)
 217 #else
 218 #define LSPAN(type)     (round8(sizeof (type)) + 8)
 219 #endif
 220 
 221 static void rebuild_objdir(struct as *);


 570                 else
 571                         allsetrun(p);
 572         }
 573 
 574         prunlock(pnp);
 575         return (0);
 576 }
 577 
 578 /*
 579  * Array of read functions, indexed by /proc file type.
 580  */
 581 static int pr_read_inval(), pr_read_as(), pr_read_status(),
 582         pr_read_lstatus(), pr_read_psinfo(), pr_read_lpsinfo(),
 583         pr_read_map(), pr_read_rmap(), pr_read_xmap(),
 584         pr_read_cred(), pr_read_sigact(), pr_read_auxv(),
 585 #if defined(__x86)
 586         pr_read_ldt(),
 587 #endif
 588         pr_read_usage(), pr_read_lusage(), pr_read_pagedata(),
 589         pr_read_watch(), pr_read_lwpstatus(), pr_read_lwpsinfo(),
 590         pr_read_lwpusage(), pr_read_xregs(), pr_read_priv(),

 591         pr_read_spymaster(), pr_read_secflags(),
 592 #if defined(__sparc)
 593         pr_read_gwindows(), pr_read_asrs(),
 594 #endif
 595         pr_read_piddir(), pr_read_pidfile(), pr_read_opagedata();
 596 
 597 static int (*pr_read_function[PR_NFILES])() = {
 598         pr_read_inval,          /* /proc                                */
 599         pr_read_inval,          /* /proc/self                           */
 600         pr_read_piddir,         /* /proc/<pid> (old /proc read()) */
 601         pr_read_as,             /* /proc/<pid>/as                 */
 602         pr_read_inval,          /* /proc/<pid>/ctl                        */
 603         pr_read_status,         /* /proc/<pid>/status                     */
 604         pr_read_lstatus,        /* /proc/<pid>/lstatus                    */
 605         pr_read_psinfo,         /* /proc/<pid>/psinfo                     */
 606         pr_read_lpsinfo,        /* /proc/<pid>/lpsinfo                    */
 607         pr_read_map,            /* /proc/<pid>/map                        */
 608         pr_read_rmap,           /* /proc/<pid>/rmap                       */
 609         pr_read_xmap,           /* /proc/<pid>/xmap                       */
 610         pr_read_cred,           /* /proc/<pid>/cred                       */
 611         pr_read_sigact,         /* /proc/<pid>/sigact                     */
 612         pr_read_auxv,           /* /proc/<pid>/auxv                       */
 613 #if defined(__x86)
 614         pr_read_ldt,            /* /proc/<pid>/ldt                        */
 615 #endif
 616         pr_read_usage,          /* /proc/<pid>/usage                      */
 617         pr_read_lusage,         /* /proc/<pid>/lusage                     */
 618         pr_read_pagedata,       /* /proc/<pid>/pagedata                   */
 619         pr_read_watch,          /* /proc/<pid>/watch                      */
 620         pr_read_inval,          /* /proc/<pid>/cwd                        */
 621         pr_read_inval,          /* /proc/<pid>/root                       */
 622         pr_read_inval,          /* /proc/<pid>/fd                 */
 623         pr_read_inval,          /* /proc/<pid>/fd/nn                      */
 624         pr_read_inval,          /* /proc/<pid>/object                     */
 625         pr_read_inval,          /* /proc/<pid>/object/xxx         */
 626         pr_read_inval,          /* /proc/<pid>/lwp                        */
 627         pr_read_inval,          /* /proc/<pid>/lwp/<lwpid>          */
 628         pr_read_inval,          /* /proc/<pid>/lwp/<lwpid>/lwpctl   */

 629         pr_read_lwpstatus,      /* /proc/<pid>/lwp/<lwpid>/lwpstatus        */
 630         pr_read_lwpsinfo,       /* /proc/<pid>/lwp/<lwpid>/lwpsinfo */
 631         pr_read_lwpusage,       /* /proc/<pid>/lwp/<lwpid>/lwpusage */
 632         pr_read_xregs,          /* /proc/<pid>/lwp/<lwpid>/xregs    */
 633         pr_read_inval,          /* /proc/<pid>/lwp/<lwpid>/templates        */
 634         pr_read_inval,          /* /proc/<pid>/lwp/<lwpid>/templates/<id> */
 635         pr_read_spymaster,      /* /proc/<pid>/lwp/<lwpid>/spymaster        */
 636 #if defined(__sparc)
 637         pr_read_gwindows,       /* /proc/<pid>/lwp/<lwpid>/gwindows */
 638         pr_read_asrs,           /* /proc/<pid>/lwp/<lwpid>/asrs             */
 639 #endif
 640         pr_read_priv,           /* /proc/<pid>/priv                       */
 641         pr_read_inval,          /* /proc/<pid>/path                       */
 642         pr_read_inval,          /* /proc/<pid>/path/xxx                   */
 643         pr_read_inval,          /* /proc/<pid>/contracts          */
 644         pr_read_inval,          /* /proc/<pid>/contracts/<ctid>             */
 645         pr_read_secflags,       /* /proc/<pid>/secflags                   */
 646         pr_read_pidfile,        /* old process file                     */
 647         pr_read_pidfile,        /* old lwp file                         */
 648         pr_read_opagedata,      /* old pagedata file                    */


1056         if (uiop->uio_offset >= sizeof (auxv)) {
1057                 prunlock(pnp);
1058                 return (0);
1059         }
1060 
1061         p = pnp->pr_common->prc_proc;
1062         up = PTOU(p);
1063         bcopy(up->u_auxv, auxv, sizeof (auxv));
1064         prunlock(pnp);
1065 
1066         return (pr_uioread(auxv, sizeof (auxv), uiop));
1067 }
1068 
1069 #if defined(__x86)
1070 /*
1071  * XX64
1072  *      This is almost certainly broken for the amd64 kernel, because
1073  *      we have two kinds of LDT structures to export -- one for compatibility
1074  *      mode, and one for long mode, sigh.
1075  *
1076  *      For now lets just have a ldt of size 0 for 64-bit processes.
1077  */
1078 static int
1079 pr_read_ldt(prnode_t *pnp, uio_t *uiop)
1080 {
1081         proc_t *p;
1082         struct ssd *ssd;
1083         size_t size;
1084         int error;
1085 
1086         ASSERT(pnp->pr_type == PR_LDT);
1087 
1088         if ((error = prlock(pnp, ZNO)) != 0)
1089                 return (error);
1090         p = pnp->pr_common->prc_proc;
1091 
1092         mutex_exit(&p->p_lock);
1093         mutex_enter(&p->p_ldtlock);
1094         size = prnldt(p) * sizeof (struct ssd);
1095         if (uiop->uio_offset >= size) {
1096                 mutex_exit(&p->p_ldtlock);


1521         if (uiop->uio_offset >= sizeof (prusage_t)) {
1522                 prunlock(pnp);
1523                 error = 0;
1524                 goto out;
1525         }
1526 
1527         pup->pr_tstamp = gethrtime();
1528         prgetusage(pnp->pr_common->prc_thread, pup);
1529 
1530         prunlock(pnp);
1531 
1532         prcvtusage(pup, upup);
1533 
1534         error = pr_uioread(upup, sizeof (prusage_t), uiop);
1535 out:
1536         kmem_free(pup, sizeof (*pup));
1537         kmem_free(upup, sizeof (*upup));
1538         return (error);
1539 }
1540 



























1541 /* ARGSUSED */
1542 static int
1543 pr_read_xregs(prnode_t *pnp, uio_t *uiop)
1544 {
1545 #if defined(__sparc)
1546         proc_t *p;
1547         kthread_t *t;
1548         int error;
1549         char *xreg;
1550         size_t size;
1551 
1552         ASSERT(pnp->pr_type == PR_XREGS);
1553 
1554         xreg = kmem_zalloc(sizeof (prxregset_t), KM_SLEEP);
1555 
1556         if ((error = prlock(pnp, ZNO)) != 0)
1557                 goto out;
1558 
1559         p = pnp->pr_common->prc_proc;
1560         t = pnp->pr_common->prc_thread;


1791         pr_read_xmap_32,        /* /proc/<pid>/xmap                       */
1792         pr_read_cred,           /* /proc/<pid>/cred                       */
1793         pr_read_sigact_32,      /* /proc/<pid>/sigact                     */
1794         pr_read_auxv_32,        /* /proc/<pid>/auxv                       */
1795 #if defined(__x86)
1796         pr_read_ldt,            /* /proc/<pid>/ldt                        */
1797 #endif
1798         pr_read_usage_32,       /* /proc/<pid>/usage                      */
1799         pr_read_lusage_32,      /* /proc/<pid>/lusage                     */
1800         pr_read_pagedata_32,    /* /proc/<pid>/pagedata                   */
1801         pr_read_watch_32,       /* /proc/<pid>/watch                      */
1802         pr_read_inval,          /* /proc/<pid>/cwd                        */
1803         pr_read_inval,          /* /proc/<pid>/root                       */
1804         pr_read_inval,          /* /proc/<pid>/fd                 */
1805         pr_read_inval,          /* /proc/<pid>/fd/nn                      */
1806         pr_read_inval,          /* /proc/<pid>/object                     */
1807         pr_read_inval,          /* /proc/<pid>/object/xxx         */
1808         pr_read_inval,          /* /proc/<pid>/lwp                        */
1809         pr_read_inval,          /* /proc/<pid>/lwp/<lwpid>          */
1810         pr_read_inval,          /* /proc/<pid>/lwp/<lwpid>/lwpctl   */

1811         pr_read_lwpstatus_32,   /* /proc/<pid>/lwp/<lwpid>/lwpstatus        */
1812         pr_read_lwpsinfo_32,    /* /proc/<pid>/lwp/<lwpid>/lwpsinfo */
1813         pr_read_lwpusage_32,    /* /proc/<pid>/lwp/<lwpid>/lwpusage */
1814         pr_read_xregs,          /* /proc/<pid>/lwp/<lwpid>/xregs    */
1815         pr_read_inval,          /* /proc/<pid>/lwp/<lwpid>/templates        */
1816         pr_read_inval,          /* /proc/<pid>/lwp/<lwpid>/templates/<id> */
1817         pr_read_spymaster_32,   /* /proc/<pid>/lwp/<lwpid>/spymaster        */
1818 #if defined(__sparc)
1819         pr_read_gwindows_32,    /* /proc/<pid>/lwp/<lwpid>/gwindows */
1820         pr_read_asrs,           /* /proc/<pid>/lwp/<lwpid>/asrs             */
1821 #endif
1822         pr_read_priv,           /* /proc/<pid>/priv                       */
1823         pr_read_inval,          /* /proc/<pid>/path                       */
1824         pr_read_inval,          /* /proc/<pid>/path/xxx                   */
1825         pr_read_inval,          /* /proc/<pid>/contracts          */
1826         pr_read_inval,          /* /proc/<pid>/contracts/<ctid>             */
1827         pr_read_secflags,       /* /proc/<pid>/secflags                   */
1828         pr_read_pidfile,        /* old process file                     */
1829         pr_read_pidfile,        /* old lwp file                         */
1830         pr_read_opagedata_32,   /* old pagedata file                    */


2703 {
2704         prnode_t *pnp = VTOP(vp);
2705 
2706         ASSERT(pnp->pr_type < PR_NFILES);
2707 
2708 #ifdef _SYSCALL32_IMPL
2709         /*
2710          * What is read from the /proc files depends on the data
2711          * model of the caller.  An LP64 process will see LP64
2712          * data.  An ILP32 process will see ILP32 data.
2713          */
2714         if (curproc->p_model == DATAMODEL_LP64)
2715                 return (pr_read_function[pnp->pr_type](pnp, uiop));
2716         else
2717                 return (pr_read_function_32[pnp->pr_type](pnp, uiop));
2718 #else
2719         return (pr_read_function[pnp->pr_type](pnp, uiop));
2720 #endif
2721 }
2722 
















































2723 /* ARGSUSED */
2724 static int
2725 prwrite(vnode_t *vp, uio_t *uiop, int ioflag, cred_t *cr, caller_context_t *ct)
2726 {
2727         prnode_t *pnp = VTOP(vp);
2728         int old = 0;
2729         int error;
2730         ssize_t resid;
2731 
2732         ASSERT(pnp->pr_type < PR_NFILES);
2733 
2734         /*
2735          * Only a handful of /proc files are writable, enumerate them here.
2736          */
2737         switch (pnp->pr_type) {
2738         case PR_PIDDIR:         /* directory write()s: visceral revulsion. */
2739                 ASSERT(pnp->pr_pidfile != NULL);
2740                 /* use the underlying PR_PIDFILE to write the process */
2741                 vp = pnp->pr_pidfile;
2742                 pnp = VTOP(vp);


2781                  * Perform the action on the control file
2782                  * by passing curthreads credentials
2783                  * and not target process's credentials.
2784                  */
2785 #ifdef _SYSCALL32_IMPL
2786                 if (curproc->p_model == DATAMODEL_ILP32)
2787                         error = prwritectl32(vp, uiop, CRED());
2788                 else
2789                         error = prwritectl(vp, uiop, CRED());
2790 #else
2791                 error = prwritectl(vp, uiop, CRED());
2792 #endif
2793                 /*
2794                  * This hack makes sure that the EINTR is passed
2795                  * all the way back to the caller's write() call.
2796                  */
2797                 if (error == EINTR)
2798                         uiop->uio_resid = resid;
2799                 return (error);
2800 



2801         default:
2802                 return ((vp->v_type == VDIR)? EISDIR : EBADF);
2803         }
2804         /* NOTREACHED */
2805 }
2806 
2807 static int
2808 prgetattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr,
2809     caller_context_t *ct)
2810 {
2811         prnode_t *pnp = VTOP(vp);
2812         prnodetype_t type = pnp->pr_type;
2813         prcommon_t *pcp;
2814         proc_t *p;
2815         struct as *as;
2816         int error;
2817         vnode_t *rvp;
2818         timestruc_t now;
2819         extern uint_t nproc;
2820         int ngroups;


3341         pr_lookup_notdir,       /* /proc/<pid>/xmap                       */
3342         pr_lookup_notdir,       /* /proc/<pid>/cred                       */
3343         pr_lookup_notdir,       /* /proc/<pid>/sigact                     */
3344         pr_lookup_notdir,       /* /proc/<pid>/auxv                       */
3345 #if defined(__x86)
3346         pr_lookup_notdir,       /* /proc/<pid>/ldt                        */
3347 #endif
3348         pr_lookup_notdir,       /* /proc/<pid>/usage                      */
3349         pr_lookup_notdir,       /* /proc/<pid>/lusage                     */
3350         pr_lookup_notdir,       /* /proc/<pid>/pagedata                   */
3351         pr_lookup_notdir,       /* /proc/<pid>/watch                      */
3352         pr_lookup_notdir,       /* /proc/<pid>/cwd                        */
3353         pr_lookup_notdir,       /* /proc/<pid>/root                       */
3354         pr_lookup_fddir,        /* /proc/<pid>/fd                 */
3355         pr_lookup_notdir,       /* /proc/<pid>/fd/nn                      */
3356         pr_lookup_objectdir,    /* /proc/<pid>/object                     */
3357         pr_lookup_notdir,       /* /proc/<pid>/object/xxx         */
3358         pr_lookup_lwpdir,       /* /proc/<pid>/lwp                        */
3359         pr_lookup_lwpiddir,     /* /proc/<pid>/lwp/<lwpid>          */
3360         pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/lwpctl   */

3361         pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/lwpstatus        */
3362         pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/lwpsinfo */
3363         pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/lwpusage */
3364         pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/xregs    */
3365         pr_lookup_tmpldir,      /* /proc/<pid>/lwp/<lwpid>/templates        */
3366         pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/templates/<id> */
3367         pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/spymaster        */
3368 #if defined(__sparc)
3369         pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/gwindows */
3370         pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/asrs             */
3371 #endif
3372         pr_lookup_notdir,       /* /proc/<pid>/priv                       */
3373         pr_lookup_pathdir,      /* /proc/<pid>/path                       */
3374         pr_lookup_notdir,       /* /proc/<pid>/path/xxx                   */
3375         pr_lookup_ctdir,        /* /proc/<pid>/contracts          */
3376         pr_lookup_notdir,       /* /proc/<pid>/contracts/<ctid>             */
3377         pr_lookup_notdir,       /* /proc/<pid>/secflags                   */
3378         pr_lookup_notdir,       /* old process file                     */
3379         pr_lookup_notdir,       /* old lwp file                         */
3380         pr_lookup_notdir,       /* old pagedata file                    */


4604         case PR_LWPDIR:
4605                 vp->v_type = VDIR;
4606                 pnp->pr_mode = 0555; /* read-search by all */
4607                 break;
4608 
4609         case PR_AS:
4610         case PR_TMPL:
4611                 pnp->pr_mode = 0600; /* read-write by owner only */
4612                 break;
4613 
4614         case PR_CTL:
4615         case PR_LWPCTL:
4616                 pnp->pr_mode = 0200; /* write-only by owner only */
4617                 break;
4618 
4619         case PR_PIDFILE:
4620         case PR_LWPIDFILE:
4621                 pnp->pr_mode = 0600; /* read-write by owner only */
4622                 break;
4623 




4624         case PR_PSINFO:
4625         case PR_LPSINFO:
4626         case PR_LWPSINFO:
4627         case PR_USAGE:
4628         case PR_LUSAGE:
4629         case PR_LWPUSAGE:
4630                 pnp->pr_mode = 0444; /* read-only by all */
4631                 break;
4632 
4633         default:
4634                 pnp->pr_mode = 0400; /* read-only by owner only */
4635                 break;
4636         }
4637         vn_exists(vp);
4638         return (pnp);
4639 }
4640 
4641 /*
4642  * Free the storage obtained from prgetnode().
4643  */


4728         pr_readdir_notdir,      /* /proc/<pid>/xmap                       */
4729         pr_readdir_notdir,      /* /proc/<pid>/cred                       */
4730         pr_readdir_notdir,      /* /proc/<pid>/sigact                     */
4731         pr_readdir_notdir,      /* /proc/<pid>/auxv                       */
4732 #if defined(__x86)
4733         pr_readdir_notdir,      /* /proc/<pid>/ldt                        */
4734 #endif
4735         pr_readdir_notdir,      /* /proc/<pid>/usage                      */
4736         pr_readdir_notdir,      /* /proc/<pid>/lusage                     */
4737         pr_readdir_notdir,      /* /proc/<pid>/pagedata                   */
4738         pr_readdir_notdir,      /* /proc/<pid>/watch                      */
4739         pr_readdir_notdir,      /* /proc/<pid>/cwd                        */
4740         pr_readdir_notdir,      /* /proc/<pid>/root                       */
4741         pr_readdir_fddir,       /* /proc/<pid>/fd                 */
4742         pr_readdir_notdir,      /* /proc/<pid>/fd/nn                      */
4743         pr_readdir_objectdir,   /* /proc/<pid>/object                     */
4744         pr_readdir_notdir,      /* /proc/<pid>/object/xxx         */
4745         pr_readdir_lwpdir,      /* /proc/<pid>/lwp                        */
4746         pr_readdir_lwpiddir,    /* /proc/<pid>/lwp/<lwpid>          */
4747         pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/lwpctl   */

4748         pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/lwpstatus        */
4749         pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/lwpsinfo */
4750         pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/lwpusage */
4751         pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/xregs    */
4752         pr_readdir_tmpldir,     /* /proc/<pid>/lwp/<lwpid>/templates        */
4753         pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/templates/<id> */
4754         pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/spymaster        */
4755 #if defined(__sparc)
4756         pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/gwindows */
4757         pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/asrs             */
4758 #endif
4759         pr_readdir_notdir,      /* /proc/<pid>/priv                       */
4760         pr_readdir_pathdir,     /* /proc/<pid>/path                       */
4761         pr_readdir_notdir,      /* /proc/<pid>/path/xxx                   */
4762         pr_readdir_ctdir,       /* /proc/<pid>/contracts          */
4763         pr_readdir_notdir,      /* /proc/<pid>/contracts/<ctid>             */
4764         pr_readdir_notdir,      /* /proc/<pid>/secflags                   */
4765         pr_readdir_notdir,      /* old process file                     */
4766         pr_readdir_notdir,      /* old lwp file                         */
4767         pr_readdir_notdir,      /* old pagedata file                    */




   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright (c) 2018, Joyent, Inc.
  25  * Copyright (c) 2017 by Delphix. All rights reserved.
  26  */
  27 
  28 /*      Copyright (c) 1984,      1986, 1987, 1988, 1989 AT&T        */
  29 /*        All Rights Reserved   */
  30 
  31 #include <sys/types.h>
  32 #include <sys/param.h>
  33 #include <sys/time.h>
  34 #include <sys/cred.h>
  35 #include <sys/policy.h>
  36 #include <sys/debug.h>
  37 #include <sys/dirent.h>
  38 #include <sys/errno.h>
  39 #include <sys/file.h>
  40 #include <sys/inline.h>
  41 #include <sys/kmem.h>
  42 #include <sys/pathname.h>
  43 #include <sys/proc.h>
  44 #include <sys/brand.h>


  47 #include <sys/sysmacros.h>
  48 #include <sys/systm.h>
  49 #include <sys/zone.h>
  50 #include <sys/uio.h>
  51 #include <sys/var.h>
  52 #include <sys/mode.h>
  53 #include <sys/poll.h>
  54 #include <sys/user.h>
  55 #include <sys/vfs.h>
  56 #include <sys/vfs_opreg.h>
  57 #include <sys/gfs.h>
  58 #include <sys/vnode.h>
  59 #include <sys/fault.h>
  60 #include <sys/syscall.h>
  61 #include <sys/procfs.h>
  62 #include <sys/atomic.h>
  63 #include <sys/cmn_err.h>
  64 #include <sys/contract_impl.h>
  65 #include <sys/ctfs.h>
  66 #include <sys/avl.h>
  67 #include <sys/ctype.h>
  68 #include <fs/fs_subr.h>
  69 #include <vm/rm.h>
  70 #include <vm/as.h>
  71 #include <vm/seg.h>
  72 #include <vm/seg_vn.h>
  73 #include <vm/hat.h>
  74 #include <fs/proc/prdata.h>
  75 #if defined(__sparc)
  76 #include <sys/regset.h>
  77 #endif
  78 #if defined(__x86)
  79 #include <sys/sysi86.h>
  80 #endif
  81 
  82 /*
  83  * Created by prinit.
  84  */
  85 vnodeops_t *prvnodeops;
  86 
  87 /*


 167         { PR_SECFLAGS,  27 * sizeof (prdirent_t), sizeof (prdirent_t),
 168                 "secflags" },
 169 #if defined(__x86)
 170         { PR_LDT,       28 * sizeof (prdirent_t), sizeof (prdirent_t),
 171                 "ldt" },
 172 #endif
 173 };
 174 
 175 #define NPIDDIRFILES    (sizeof (piddir) / sizeof (piddir[0]) - 2)
 176 
 177 /*
 178  * Contents of a /proc/<pid>/lwp/<lwpid> directory.
 179  */
 180 static prdirent_t lwpiddir[] = {
 181         { PR_LWPIDDIR,   1 * sizeof (prdirent_t), sizeof (prdirent_t),
 182                 "." },
 183         { PR_LWPDIR,     2 * sizeof (prdirent_t), sizeof (prdirent_t),
 184                 ".." },
 185         { PR_LWPCTL,     3 * sizeof (prdirent_t), sizeof (prdirent_t),
 186                 "lwpctl" },
 187         { PR_LWPNAME,    4 * sizeof (prdirent_t), sizeof (prdirent_t),
 188                 "lwpname" },
 189         { PR_LWPSTATUS,  5 * sizeof (prdirent_t), sizeof (prdirent_t),
 190                 "lwpstatus" },
 191         { PR_LWPSINFO,   6 * sizeof (prdirent_t), sizeof (prdirent_t),
 192                 "lwpsinfo" },
 193         { PR_LWPUSAGE,   7 * sizeof (prdirent_t), sizeof (prdirent_t),
 194                 "lwpusage" },
 195         { PR_XREGS,      8 * sizeof (prdirent_t), sizeof (prdirent_t),
 196                 "xregs" },
 197         { PR_TMPLDIR,    9 * sizeof (prdirent_t), sizeof (prdirent_t),
 198                 "templates" },
 199         { PR_SPYMASTER,  10 * sizeof (prdirent_t), sizeof (prdirent_t),
 200                 "spymaster" },
 201 #if defined(__sparc)
 202         { PR_GWINDOWS,  11 * sizeof (prdirent_t), sizeof (prdirent_t),
 203                 "gwindows" },
 204         { PR_ASRS,      12 * sizeof (prdirent_t), sizeof (prdirent_t),
 205                 "asrs" },
 206 #endif
 207 };
 208 
 209 #define NLWPIDDIRFILES  (sizeof (lwpiddir) / sizeof (lwpiddir[0]) - 2)
 210 
 211 /*
 212  * Span of entries in the array files (lstatus, lpsinfo, lusage).
 213  * We make the span larger than the size of the structure on purpose,
 214  * to make sure that programs cannot use the structure size by mistake.
 215  * Align _ILP32 structures at 8 bytes, _LP64 structures at 16 bytes.
 216  */
 217 #ifdef _LP64
 218 #define LSPAN(type)     (round16(sizeof (type)) + 16)
 219 #define LSPAN32(type)   (round8(sizeof (type)) + 8)
 220 #else
 221 #define LSPAN(type)     (round8(sizeof (type)) + 8)
 222 #endif
 223 
 224 static void rebuild_objdir(struct as *);


 573                 else
 574                         allsetrun(p);
 575         }
 576 
 577         prunlock(pnp);
 578         return (0);
 579 }
 580 
 581 /*
 582  * Array of read functions, indexed by /proc file type.
 583  */
 584 static int pr_read_inval(), pr_read_as(), pr_read_status(),
 585         pr_read_lstatus(), pr_read_psinfo(), pr_read_lpsinfo(),
 586         pr_read_map(), pr_read_rmap(), pr_read_xmap(),
 587         pr_read_cred(), pr_read_sigact(), pr_read_auxv(),
 588 #if defined(__x86)
 589         pr_read_ldt(),
 590 #endif
 591         pr_read_usage(), pr_read_lusage(), pr_read_pagedata(),
 592         pr_read_watch(), pr_read_lwpstatus(), pr_read_lwpsinfo(),
 593         pr_read_lwpusage(), pr_read_lwpname(),
 594         pr_read_xregs(), pr_read_priv(),
 595         pr_read_spymaster(), pr_read_secflags(),
 596 #if defined(__sparc)
 597         pr_read_gwindows(), pr_read_asrs(),
 598 #endif
 599         pr_read_piddir(), pr_read_pidfile(), pr_read_opagedata();
 600 
 601 static int (*pr_read_function[PR_NFILES])() = {
 602         pr_read_inval,          /* /proc                                */
 603         pr_read_inval,          /* /proc/self                           */
 604         pr_read_piddir,         /* /proc/<pid> (old /proc read()) */
 605         pr_read_as,             /* /proc/<pid>/as                 */
 606         pr_read_inval,          /* /proc/<pid>/ctl                        */
 607         pr_read_status,         /* /proc/<pid>/status                     */
 608         pr_read_lstatus,        /* /proc/<pid>/lstatus                    */
 609         pr_read_psinfo,         /* /proc/<pid>/psinfo                     */
 610         pr_read_lpsinfo,        /* /proc/<pid>/lpsinfo                    */
 611         pr_read_map,            /* /proc/<pid>/map                        */
 612         pr_read_rmap,           /* /proc/<pid>/rmap                       */
 613         pr_read_xmap,           /* /proc/<pid>/xmap                       */
 614         pr_read_cred,           /* /proc/<pid>/cred                       */
 615         pr_read_sigact,         /* /proc/<pid>/sigact                     */
 616         pr_read_auxv,           /* /proc/<pid>/auxv                       */
 617 #if defined(__x86)
 618         pr_read_ldt,            /* /proc/<pid>/ldt                        */
 619 #endif
 620         pr_read_usage,          /* /proc/<pid>/usage                      */
 621         pr_read_lusage,         /* /proc/<pid>/lusage                     */
 622         pr_read_pagedata,       /* /proc/<pid>/pagedata                   */
 623         pr_read_watch,          /* /proc/<pid>/watch                      */
 624         pr_read_inval,          /* /proc/<pid>/cwd                        */
 625         pr_read_inval,          /* /proc/<pid>/root                       */
 626         pr_read_inval,          /* /proc/<pid>/fd                 */
 627         pr_read_inval,          /* /proc/<pid>/fd/nn                      */
 628         pr_read_inval,          /* /proc/<pid>/object                     */
 629         pr_read_inval,          /* /proc/<pid>/object/xxx         */
 630         pr_read_inval,          /* /proc/<pid>/lwp                        */
 631         pr_read_inval,          /* /proc/<pid>/lwp/<lwpid>          */
 632         pr_read_inval,          /* /proc/<pid>/lwp/<lwpid>/lwpctl   */
 633         pr_read_lwpname,        /* /proc/<pid>/lwp/<lwpid>/lwpname  */
 634         pr_read_lwpstatus,      /* /proc/<pid>/lwp/<lwpid>/lwpstatus        */
 635         pr_read_lwpsinfo,       /* /proc/<pid>/lwp/<lwpid>/lwpsinfo */
 636         pr_read_lwpusage,       /* /proc/<pid>/lwp/<lwpid>/lwpusage */
 637         pr_read_xregs,          /* /proc/<pid>/lwp/<lwpid>/xregs    */
 638         pr_read_inval,          /* /proc/<pid>/lwp/<lwpid>/templates        */
 639         pr_read_inval,          /* /proc/<pid>/lwp/<lwpid>/templates/<id> */
 640         pr_read_spymaster,      /* /proc/<pid>/lwp/<lwpid>/spymaster        */
 641 #if defined(__sparc)
 642         pr_read_gwindows,       /* /proc/<pid>/lwp/<lwpid>/gwindows */
 643         pr_read_asrs,           /* /proc/<pid>/lwp/<lwpid>/asrs             */
 644 #endif
 645         pr_read_priv,           /* /proc/<pid>/priv                       */
 646         pr_read_inval,          /* /proc/<pid>/path                       */
 647         pr_read_inval,          /* /proc/<pid>/path/xxx                   */
 648         pr_read_inval,          /* /proc/<pid>/contracts          */
 649         pr_read_inval,          /* /proc/<pid>/contracts/<ctid>             */
 650         pr_read_secflags,       /* /proc/<pid>/secflags                   */
 651         pr_read_pidfile,        /* old process file                     */
 652         pr_read_pidfile,        /* old lwp file                         */
 653         pr_read_opagedata,      /* old pagedata file                    */


1061         if (uiop->uio_offset >= sizeof (auxv)) {
1062                 prunlock(pnp);
1063                 return (0);
1064         }
1065 
1066         p = pnp->pr_common->prc_proc;
1067         up = PTOU(p);
1068         bcopy(up->u_auxv, auxv, sizeof (auxv));
1069         prunlock(pnp);
1070 
1071         return (pr_uioread(auxv, sizeof (auxv), uiop));
1072 }
1073 
1074 #if defined(__x86)
1075 /*
1076  * XX64
1077  *      This is almost certainly broken for the amd64 kernel, because
1078  *      we have two kinds of LDT structures to export -- one for compatibility
1079  *      mode, and one for long mode, sigh.
1080  *
1081  *      For now let's just have a ldt of size 0 for 64-bit processes.
1082  */
1083 static int
1084 pr_read_ldt(prnode_t *pnp, uio_t *uiop)
1085 {
1086         proc_t *p;
1087         struct ssd *ssd;
1088         size_t size;
1089         int error;
1090 
1091         ASSERT(pnp->pr_type == PR_LDT);
1092 
1093         if ((error = prlock(pnp, ZNO)) != 0)
1094                 return (error);
1095         p = pnp->pr_common->prc_proc;
1096 
1097         mutex_exit(&p->p_lock);
1098         mutex_enter(&p->p_ldtlock);
1099         size = prnldt(p) * sizeof (struct ssd);
1100         if (uiop->uio_offset >= size) {
1101                 mutex_exit(&p->p_ldtlock);


1526         if (uiop->uio_offset >= sizeof (prusage_t)) {
1527                 prunlock(pnp);
1528                 error = 0;
1529                 goto out;
1530         }
1531 
1532         pup->pr_tstamp = gethrtime();
1533         prgetusage(pnp->pr_common->prc_thread, pup);
1534 
1535         prunlock(pnp);
1536 
1537         prcvtusage(pup, upup);
1538 
1539         error = pr_uioread(upup, sizeof (prusage_t), uiop);
1540 out:
1541         kmem_free(pup, sizeof (*pup));
1542         kmem_free(upup, sizeof (*upup));
1543         return (error);
1544 }
1545 
1546 static int
1547 pr_read_lwpname(prnode_t *pnp, uio_t *uiop)
1548 {
1549         char lwpname[THREAD_NAME_MAX];
1550         kthread_t *t;
1551         int error;
1552 
1553         ASSERT(pnp->pr_type == PR_LWPNAME);
1554 
1555         if (uiop->uio_offset >= THREAD_NAME_MAX)
1556                 return (0);
1557 
1558         if ((error = prlock(pnp, ZNO)) != 0)
1559                 return (error);
1560 
1561         bzero(lwpname, sizeof (lwpname));
1562 
1563         t = pnp->pr_common->prc_thread;
1564 
1565         if (t->t_name != NULL)
1566                 (void) strlcpy(lwpname, t->t_name, sizeof (lwpname));
1567 
1568         prunlock(pnp);
1569 
1570         return (pr_uioread(lwpname, sizeof (lwpname), uiop));
1571 }
1572 
1573 /* ARGSUSED */
1574 static int
1575 pr_read_xregs(prnode_t *pnp, uio_t *uiop)
1576 {
1577 #if defined(__sparc)
1578         proc_t *p;
1579         kthread_t *t;
1580         int error;
1581         char *xreg;
1582         size_t size;
1583 
1584         ASSERT(pnp->pr_type == PR_XREGS);
1585 
1586         xreg = kmem_zalloc(sizeof (prxregset_t), KM_SLEEP);
1587 
1588         if ((error = prlock(pnp, ZNO)) != 0)
1589                 goto out;
1590 
1591         p = pnp->pr_common->prc_proc;
1592         t = pnp->pr_common->prc_thread;


1823         pr_read_xmap_32,        /* /proc/<pid>/xmap                       */
1824         pr_read_cred,           /* /proc/<pid>/cred                       */
1825         pr_read_sigact_32,      /* /proc/<pid>/sigact                     */
1826         pr_read_auxv_32,        /* /proc/<pid>/auxv                       */
1827 #if defined(__x86)
1828         pr_read_ldt,            /* /proc/<pid>/ldt                        */
1829 #endif
1830         pr_read_usage_32,       /* /proc/<pid>/usage                      */
1831         pr_read_lusage_32,      /* /proc/<pid>/lusage                     */
1832         pr_read_pagedata_32,    /* /proc/<pid>/pagedata                   */
1833         pr_read_watch_32,       /* /proc/<pid>/watch                      */
1834         pr_read_inval,          /* /proc/<pid>/cwd                        */
1835         pr_read_inval,          /* /proc/<pid>/root                       */
1836         pr_read_inval,          /* /proc/<pid>/fd                 */
1837         pr_read_inval,          /* /proc/<pid>/fd/nn                      */
1838         pr_read_inval,          /* /proc/<pid>/object                     */
1839         pr_read_inval,          /* /proc/<pid>/object/xxx         */
1840         pr_read_inval,          /* /proc/<pid>/lwp                        */
1841         pr_read_inval,          /* /proc/<pid>/lwp/<lwpid>          */
1842         pr_read_inval,          /* /proc/<pid>/lwp/<lwpid>/lwpctl   */
1843         pr_read_lwpname,        /* /proc/<pid>/lwp/<lwpid>/lwpname  */
1844         pr_read_lwpstatus_32,   /* /proc/<pid>/lwp/<lwpid>/lwpstatus        */
1845         pr_read_lwpsinfo_32,    /* /proc/<pid>/lwp/<lwpid>/lwpsinfo */
1846         pr_read_lwpusage_32,    /* /proc/<pid>/lwp/<lwpid>/lwpusage */
1847         pr_read_xregs,          /* /proc/<pid>/lwp/<lwpid>/xregs    */
1848         pr_read_inval,          /* /proc/<pid>/lwp/<lwpid>/templates        */
1849         pr_read_inval,          /* /proc/<pid>/lwp/<lwpid>/templates/<id> */
1850         pr_read_spymaster_32,   /* /proc/<pid>/lwp/<lwpid>/spymaster        */
1851 #if defined(__sparc)
1852         pr_read_gwindows_32,    /* /proc/<pid>/lwp/<lwpid>/gwindows */
1853         pr_read_asrs,           /* /proc/<pid>/lwp/<lwpid>/asrs             */
1854 #endif
1855         pr_read_priv,           /* /proc/<pid>/priv                       */
1856         pr_read_inval,          /* /proc/<pid>/path                       */
1857         pr_read_inval,          /* /proc/<pid>/path/xxx                   */
1858         pr_read_inval,          /* /proc/<pid>/contracts          */
1859         pr_read_inval,          /* /proc/<pid>/contracts/<ctid>             */
1860         pr_read_secflags,       /* /proc/<pid>/secflags                   */
1861         pr_read_pidfile,        /* old process file                     */
1862         pr_read_pidfile,        /* old lwp file                         */
1863         pr_read_opagedata_32,   /* old pagedata file                    */


2736 {
2737         prnode_t *pnp = VTOP(vp);
2738 
2739         ASSERT(pnp->pr_type < PR_NFILES);
2740 
2741 #ifdef _SYSCALL32_IMPL
2742         /*
2743          * What is read from the /proc files depends on the data
2744          * model of the caller.  An LP64 process will see LP64
2745          * data.  An ILP32 process will see ILP32 data.
2746          */
2747         if (curproc->p_model == DATAMODEL_LP64)
2748                 return (pr_read_function[pnp->pr_type](pnp, uiop));
2749         else
2750                 return (pr_read_function_32[pnp->pr_type](pnp, uiop));
2751 #else
2752         return (pr_read_function[pnp->pr_type](pnp, uiop));
2753 #endif
2754 }
2755 
2756 /* Note we intentionally don't handle partial writes/updates. */
2757 static int
2758 pr_write_lwpname(prnode_t *pnp, uio_t *uiop)
2759 {
2760         kthread_t *t = NULL;
2761         char *lwpname;
2762         int error;
2763 
2764         lwpname = kmem_zalloc(THREAD_NAME_MAX, KM_SLEEP);
2765 
2766         if ((error = uiomove(lwpname, THREAD_NAME_MAX, UIO_WRITE, uiop)) != 0) {
2767                 kmem_free(lwpname, THREAD_NAME_MAX);
2768                 return (error);
2769         }
2770 
2771         /* Somebody tried to write too long a thread name... */
2772         if (lwpname[THREAD_NAME_MAX - 1] != '\0' || uiop->uio_resid > 0) {
2773                 kmem_free(lwpname, THREAD_NAME_MAX);
2774                 return (EIO);
2775         }
2776 
2777         VERIFY3U(lwpname[THREAD_NAME_MAX - 1], ==, '\0');
2778 
2779         for (size_t i = 0; lwpname[i] != '\0'; i++) {
2780                 if (!ISPRINT(lwpname[i])) {
2781                         kmem_free(lwpname, THREAD_NAME_MAX);
2782                         return (EINVAL);
2783                 }
2784         }
2785 
2786         /* Equivalent of thread_setname(), but with the ZNO magic. */
2787         if ((error = prlock(pnp, ZNO)) != 0) {
2788                 kmem_free(lwpname, THREAD_NAME_MAX);
2789                 return (error);
2790         }
2791 
2792         t = pnp->pr_common->prc_thread;
2793         if (t->t_name == NULL) {
2794                 t->t_name = lwpname;
2795         } else {
2796                 (void) strlcpy(t->t_name, lwpname, THREAD_NAME_MAX);
2797                 kmem_free(lwpname, THREAD_NAME_MAX);
2798         }
2799 
2800         prunlock(pnp);
2801         return (0);
2802 }
2803 
2804 /* ARGSUSED */
2805 static int
2806 prwrite(vnode_t *vp, uio_t *uiop, int ioflag, cred_t *cr, caller_context_t *ct)
2807 {
2808         prnode_t *pnp = VTOP(vp);
2809         int old = 0;
2810         int error;
2811         ssize_t resid;
2812 
2813         ASSERT(pnp->pr_type < PR_NFILES);
2814 
2815         /*
2816          * Only a handful of /proc files are writable, enumerate them here.
2817          */
2818         switch (pnp->pr_type) {
2819         case PR_PIDDIR:         /* directory write()s: visceral revulsion. */
2820                 ASSERT(pnp->pr_pidfile != NULL);
2821                 /* use the underlying PR_PIDFILE to write the process */
2822                 vp = pnp->pr_pidfile;
2823                 pnp = VTOP(vp);


2862                  * Perform the action on the control file
2863                  * by passing curthreads credentials
2864                  * and not target process's credentials.
2865                  */
2866 #ifdef _SYSCALL32_IMPL
2867                 if (curproc->p_model == DATAMODEL_ILP32)
2868                         error = prwritectl32(vp, uiop, CRED());
2869                 else
2870                         error = prwritectl(vp, uiop, CRED());
2871 #else
2872                 error = prwritectl(vp, uiop, CRED());
2873 #endif
2874                 /*
2875                  * This hack makes sure that the EINTR is passed
2876                  * all the way back to the caller's write() call.
2877                  */
2878                 if (error == EINTR)
2879                         uiop->uio_resid = resid;
2880                 return (error);
2881 
2882         case PR_LWPNAME:
2883                 return (pr_write_lwpname(pnp, uiop));
2884 
2885         default:
2886                 return ((vp->v_type == VDIR)? EISDIR : EBADF);
2887         }
2888         /* NOTREACHED */
2889 }
2890 
2891 static int
2892 prgetattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr,
2893     caller_context_t *ct)
2894 {
2895         prnode_t *pnp = VTOP(vp);
2896         prnodetype_t type = pnp->pr_type;
2897         prcommon_t *pcp;
2898         proc_t *p;
2899         struct as *as;
2900         int error;
2901         vnode_t *rvp;
2902         timestruc_t now;
2903         extern uint_t nproc;
2904         int ngroups;


3425         pr_lookup_notdir,       /* /proc/<pid>/xmap                       */
3426         pr_lookup_notdir,       /* /proc/<pid>/cred                       */
3427         pr_lookup_notdir,       /* /proc/<pid>/sigact                     */
3428         pr_lookup_notdir,       /* /proc/<pid>/auxv                       */
3429 #if defined(__x86)
3430         pr_lookup_notdir,       /* /proc/<pid>/ldt                        */
3431 #endif
3432         pr_lookup_notdir,       /* /proc/<pid>/usage                      */
3433         pr_lookup_notdir,       /* /proc/<pid>/lusage                     */
3434         pr_lookup_notdir,       /* /proc/<pid>/pagedata                   */
3435         pr_lookup_notdir,       /* /proc/<pid>/watch                      */
3436         pr_lookup_notdir,       /* /proc/<pid>/cwd                        */
3437         pr_lookup_notdir,       /* /proc/<pid>/root                       */
3438         pr_lookup_fddir,        /* /proc/<pid>/fd                 */
3439         pr_lookup_notdir,       /* /proc/<pid>/fd/nn                      */
3440         pr_lookup_objectdir,    /* /proc/<pid>/object                     */
3441         pr_lookup_notdir,       /* /proc/<pid>/object/xxx         */
3442         pr_lookup_lwpdir,       /* /proc/<pid>/lwp                        */
3443         pr_lookup_lwpiddir,     /* /proc/<pid>/lwp/<lwpid>          */
3444         pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/lwpctl   */
3445         pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/lwpname  */
3446         pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/lwpstatus        */
3447         pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/lwpsinfo */
3448         pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/lwpusage */
3449         pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/xregs    */
3450         pr_lookup_tmpldir,      /* /proc/<pid>/lwp/<lwpid>/templates        */
3451         pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/templates/<id> */
3452         pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/spymaster        */
3453 #if defined(__sparc)
3454         pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/gwindows */
3455         pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/asrs             */
3456 #endif
3457         pr_lookup_notdir,       /* /proc/<pid>/priv                       */
3458         pr_lookup_pathdir,      /* /proc/<pid>/path                       */
3459         pr_lookup_notdir,       /* /proc/<pid>/path/xxx                   */
3460         pr_lookup_ctdir,        /* /proc/<pid>/contracts          */
3461         pr_lookup_notdir,       /* /proc/<pid>/contracts/<ctid>             */
3462         pr_lookup_notdir,       /* /proc/<pid>/secflags                   */
3463         pr_lookup_notdir,       /* old process file                     */
3464         pr_lookup_notdir,       /* old lwp file                         */
3465         pr_lookup_notdir,       /* old pagedata file                    */


4689         case PR_LWPDIR:
4690                 vp->v_type = VDIR;
4691                 pnp->pr_mode = 0555; /* read-search by all */
4692                 break;
4693 
4694         case PR_AS:
4695         case PR_TMPL:
4696                 pnp->pr_mode = 0600; /* read-write by owner only */
4697                 break;
4698 
4699         case PR_CTL:
4700         case PR_LWPCTL:
4701                 pnp->pr_mode = 0200; /* write-only by owner only */
4702                 break;
4703 
4704         case PR_PIDFILE:
4705         case PR_LWPIDFILE:
4706                 pnp->pr_mode = 0600; /* read-write by owner only */
4707                 break;
4708 
4709         case PR_LWPNAME:
4710                 pnp->pr_mode = 0644; /* readable by all + owner can write */
4711                 break;
4712 
4713         case PR_PSINFO:
4714         case PR_LPSINFO:
4715         case PR_LWPSINFO:
4716         case PR_USAGE:
4717         case PR_LUSAGE:
4718         case PR_LWPUSAGE:
4719                 pnp->pr_mode = 0444; /* read-only by all */
4720                 break;
4721 
4722         default:
4723                 pnp->pr_mode = 0400; /* read-only by owner only */
4724                 break;
4725         }
4726         vn_exists(vp);
4727         return (pnp);
4728 }
4729 
4730 /*
4731  * Free the storage obtained from prgetnode().
4732  */


4817         pr_readdir_notdir,      /* /proc/<pid>/xmap                       */
4818         pr_readdir_notdir,      /* /proc/<pid>/cred                       */
4819         pr_readdir_notdir,      /* /proc/<pid>/sigact                     */
4820         pr_readdir_notdir,      /* /proc/<pid>/auxv                       */
4821 #if defined(__x86)
4822         pr_readdir_notdir,      /* /proc/<pid>/ldt                        */
4823 #endif
4824         pr_readdir_notdir,      /* /proc/<pid>/usage                      */
4825         pr_readdir_notdir,      /* /proc/<pid>/lusage                     */
4826         pr_readdir_notdir,      /* /proc/<pid>/pagedata                   */
4827         pr_readdir_notdir,      /* /proc/<pid>/watch                      */
4828         pr_readdir_notdir,      /* /proc/<pid>/cwd                        */
4829         pr_readdir_notdir,      /* /proc/<pid>/root                       */
4830         pr_readdir_fddir,       /* /proc/<pid>/fd                 */
4831         pr_readdir_notdir,      /* /proc/<pid>/fd/nn                      */
4832         pr_readdir_objectdir,   /* /proc/<pid>/object                     */
4833         pr_readdir_notdir,      /* /proc/<pid>/object/xxx         */
4834         pr_readdir_lwpdir,      /* /proc/<pid>/lwp                        */
4835         pr_readdir_lwpiddir,    /* /proc/<pid>/lwp/<lwpid>          */
4836         pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/lwpctl   */
4837         pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/lwpname  */
4838         pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/lwpstatus        */
4839         pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/lwpsinfo */
4840         pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/lwpusage */
4841         pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/xregs    */
4842         pr_readdir_tmpldir,     /* /proc/<pid>/lwp/<lwpid>/templates        */
4843         pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/templates/<id> */
4844         pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/spymaster        */
4845 #if defined(__sparc)
4846         pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/gwindows */
4847         pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/asrs             */
4848 #endif
4849         pr_readdir_notdir,      /* /proc/<pid>/priv                       */
4850         pr_readdir_pathdir,     /* /proc/<pid>/path                       */
4851         pr_readdir_notdir,      /* /proc/<pid>/path/xxx                   */
4852         pr_readdir_ctdir,       /* /proc/<pid>/contracts          */
4853         pr_readdir_notdir,      /* /proc/<pid>/contracts/<ctid>             */
4854         pr_readdir_notdir,      /* /proc/<pid>/secflags                   */
4855         pr_readdir_notdir,      /* old process file                     */
4856         pr_readdir_notdir,      /* old lwp file                         */
4857         pr_readdir_notdir,      /* old pagedata file                    */