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) 2014, Joyent, Inc. All rights reserved.
  25  */
  26 
  27 /*      Copyright (c) 1984,      1986, 1987, 1988, 1989 AT&T        */
  28 /*        All Rights Reserved   */
  29 
  30 #include <sys/types.h>
  31 #include <sys/param.h>
  32 #include <sys/time.h>
  33 #include <sys/cred.h>
  34 #include <sys/policy.h>
  35 #include <sys/debug.h>
  36 #include <sys/dirent.h>
  37 #include <sys/errno.h>
  38 #include <sys/file.h>
  39 #include <sys/inline.h>
  40 #include <sys/kmem.h>
  41 #include <sys/pathname.h>
  42 #include <sys/proc.h>
  43 #include <sys/brand.h>
  44 #include <sys/signal.h>
 
 
  79 
  80 /*
  81  * Created by prinit.
  82  */
  83 vnodeops_t *prvnodeops;
  84 
  85 /*
  86  * Directory characteristics (patterned after the s5 file system).
  87  */
  88 #define PRROOTINO       2
  89 
  90 #define PRDIRSIZE       14
  91 struct prdirect {
  92         ushort_t        d_ino;
  93         char            d_name[PRDIRSIZE];
  94 };
  95 
  96 #define PRSDSIZE        (sizeof (struct prdirect))
  97 
  98 /*
  99  * Directory characteristics.
 100  */
 101 typedef struct prdirent {
 102         ino64_t         d_ino;          /* "inode number" of entry */
 103         off64_t         d_off;          /* offset of disk directory entry */
 104         unsigned short  d_reclen;       /* length of this record */
 105         char            d_name[14];     /* name of file */
 106 } prdirent_t;
 107 
 108 /*
 109  * Contents of a /proc/<pid> directory.
 110  * Reuse d_ino field for the /proc file type.
 111  */
 112 static prdirent_t piddir[] = {
 113         { PR_PIDDIR,     1 * sizeof (prdirent_t), sizeof (prdirent_t),
 114                 "." },
 115         { PR_PROCDIR,    2 * sizeof (prdirent_t), sizeof (prdirent_t),
 116                 ".." },
 117         { PR_AS,         3 * sizeof (prdirent_t), sizeof (prdirent_t),
 118                 "as" },
 
 149         { PR_CURDIR,    19 * sizeof (prdirent_t), sizeof (prdirent_t),
 150                 "cwd" },
 151         { PR_ROOTDIR,   20 * sizeof (prdirent_t), sizeof (prdirent_t),
 152                 "root" },
 153         { PR_FDDIR,     21 * sizeof (prdirent_t), sizeof (prdirent_t),
 154                 "fd" },
 155         { PR_OBJECTDIR, 22 * sizeof (prdirent_t), sizeof (prdirent_t),
 156                 "object" },
 157         { PR_LWPDIR,    23 * sizeof (prdirent_t), sizeof (prdirent_t),
 158                 "lwp" },
 159         { PR_PRIV,      24 * sizeof (prdirent_t), sizeof (prdirent_t),
 160                 "priv" },
 161         { PR_PATHDIR,   25 * sizeof (prdirent_t), sizeof (prdirent_t),
 162                 "path" },
 163         { PR_CTDIR,     26 * sizeof (prdirent_t), sizeof (prdirent_t),
 164                 "contracts" },
 165 #if defined(__x86)
 166         { PR_LDT,       27 * sizeof (prdirent_t), sizeof (prdirent_t),
 167                 "ldt" },
 168 #endif
 169 };
 170 
 171 #define NPIDDIRFILES    (sizeof (piddir) / sizeof (piddir[0]) - 2)
 172 
 173 /*
 174  * Contents of a /proc/<pid>/lwp/<lwpid> directory.
 175  */
 176 static prdirent_t lwpiddir[] = {
 177         { PR_LWPIDDIR,   1 * sizeof (prdirent_t), sizeof (prdirent_t),
 178                 "." },
 179         { PR_LWPDIR,     2 * sizeof (prdirent_t), sizeof (prdirent_t),
 180                 ".." },
 181         { PR_LWPCTL,     3 * sizeof (prdirent_t), sizeof (prdirent_t),
 182                 "lwpctl" },
 183         { PR_LWPSTATUS,  4 * sizeof (prdirent_t), sizeof (prdirent_t),
 184                 "lwpstatus" },
 185         { PR_LWPSINFO,   5 * sizeof (prdirent_t), sizeof (prdirent_t),
 186                 "lwpsinfo" },
 187         { PR_LWPUSAGE,   6 * sizeof (prdirent_t), sizeof (prdirent_t),
 188                 "lwpusage" },
 
 565                 if (killproc)
 566                         sigtoproc(p, NULL, SIGKILL);
 567                 else
 568                         allsetrun(p);
 569         }
 570 
 571         prunlock(pnp);
 572         return (0);
 573 }
 574 
 575 /*
 576  * Array of read functions, indexed by /proc file type.
 577  */
 578 static int pr_read_inval(), pr_read_as(), pr_read_status(),
 579         pr_read_lstatus(), pr_read_psinfo(), pr_read_lpsinfo(),
 580         pr_read_map(), pr_read_rmap(), pr_read_xmap(),
 581         pr_read_cred(), pr_read_sigact(), pr_read_auxv(),
 582 #if defined(__x86)
 583         pr_read_ldt(),
 584 #endif
 585         pr_read_usage(), pr_read_lusage(), pr_read_pagedata(),
 586         pr_read_watch(), pr_read_lwpstatus(), pr_read_lwpsinfo(),
 587         pr_read_lwpusage(), pr_read_xregs(), pr_read_priv(),
 588         pr_read_spymaster(),
 589 #if defined(__sparc)
 590         pr_read_gwindows(), pr_read_asrs(),
 591 #endif
 592         pr_read_piddir(), pr_read_pidfile(), pr_read_opagedata();
 593 
 594 static int (*pr_read_function[PR_NFILES])() = {
 595         pr_read_inval,          /* /proc                                */
 596         pr_read_inval,          /* /proc/self                           */
 597         pr_read_piddir,         /* /proc/<pid> (old /proc read()) */
 598         pr_read_as,             /* /proc/<pid>/as                 */
 599         pr_read_inval,          /* /proc/<pid>/ctl                        */
 600         pr_read_status,         /* /proc/<pid>/status                     */
 601         pr_read_lstatus,        /* /proc/<pid>/lstatus                    */
 602         pr_read_psinfo,         /* /proc/<pid>/psinfo                     */
 603         pr_read_lpsinfo,        /* /proc/<pid>/lpsinfo                    */
 604         pr_read_map,            /* /proc/<pid>/map                        */
 605         pr_read_rmap,           /* /proc/<pid>/rmap                       */
 606         pr_read_xmap,           /* /proc/<pid>/xmap                       */
 607         pr_read_cred,           /* /proc/<pid>/cred                       */
 608         pr_read_sigact,         /* /proc/<pid>/sigact                     */
 609         pr_read_auxv,           /* /proc/<pid>/auxv                       */
 610 #if defined(__x86)
 611         pr_read_ldt,            /* /proc/<pid>/ldt                        */
 612 #endif
 613         pr_read_usage,          /* /proc/<pid>/usage                      */
 614         pr_read_lusage,         /* /proc/<pid>/lusage                     */
 615         pr_read_pagedata,       /* /proc/<pid>/pagedata                   */
 616         pr_read_watch,          /* /proc/<pid>/watch                      */
 617         pr_read_inval,          /* /proc/<pid>/cwd                        */
 618         pr_read_inval,          /* /proc/<pid>/root                       */
 619         pr_read_inval,          /* /proc/<pid>/fd                 */
 620         pr_read_inval,          /* /proc/<pid>/fd/nn                      */
 621         pr_read_inval,          /* /proc/<pid>/object                     */
 622         pr_read_inval,          /* /proc/<pid>/object/xxx         */
 623         pr_read_inval,          /* /proc/<pid>/lwp                        */
 624         pr_read_inval,          /* /proc/<pid>/lwp/<lwpid>          */
 625         pr_read_inval,          /* /proc/<pid>/lwp/<lwpid>/lwpctl   */
 626         pr_read_lwpstatus,      /* /proc/<pid>/lwp/<lwpid>/lwpstatus        */
 627         pr_read_lwpsinfo,       /* /proc/<pid>/lwp/<lwpid>/lwpsinfo */
 628         pr_read_lwpusage,       /* /proc/<pid>/lwp/<lwpid>/lwpusage */
 629         pr_read_xregs,          /* /proc/<pid>/lwp/<lwpid>/xregs    */
 630         pr_read_inval,          /* /proc/<pid>/lwp/<lwpid>/templates        */
 631         pr_read_inval,          /* /proc/<pid>/lwp/<lwpid>/templates/<id> */
 632         pr_read_spymaster,      /* /proc/<pid>/lwp/<lwpid>/spymaster        */
 
 655          */
 656         return (EINVAL);
 657 }
 658 
 659 static int
 660 pr_uioread(void *base, long count, uio_t *uiop)
 661 {
 662         int error = 0;
 663 
 664         ASSERT(count >= 0);
 665         count -= uiop->uio_offset;
 666         if (count > 0 && uiop->uio_offset >= 0) {
 667                 error = uiomove((char *)base + uiop->uio_offset,
 668                     count, UIO_READ, uiop);
 669         }
 670 
 671         return (error);
 672 }
 673 
 674 static int
 675 pr_read_as(prnode_t *pnp, uio_t *uiop)
 676 {
 677         int error;
 678 
 679         ASSERT(pnp->pr_type == PR_AS);
 680 
 681         if ((error = prlock(pnp, ZNO)) == 0) {
 682                 proc_t *p = pnp->pr_common->prc_proc;
 683                 struct as *as = p->p_as;
 684 
 685                 /*
 686                  * /proc I/O cannot be done to a system process.
 687                  * A 32-bit process cannot read a 64-bit process.
 688                  */
 689                 if ((p->p_flag & SSYS) || as == &kas) {
 690                         error = 0;
 691 #ifdef _SYSCALL32_IMPL
 692                 } else if (curproc->p_model == DATAMODEL_ILP32 &&
 693                     PROCESS_NOT_32BIT(p)) {
 694                         error = EOVERFLOW;
 
1750 
1751 static int (*pr_read_function_32[PR_NFILES])() = {
1752         pr_read_inval,          /* /proc                                */
1753         pr_read_inval,          /* /proc/self                           */
1754         pr_read_piddir,         /* /proc/<pid> (old /proc read()) */
1755         pr_read_as,             /* /proc/<pid>/as                 */
1756         pr_read_inval,          /* /proc/<pid>/ctl                        */
1757         pr_read_status_32,      /* /proc/<pid>/status                     */
1758         pr_read_lstatus_32,     /* /proc/<pid>/lstatus                    */
1759         pr_read_psinfo_32,      /* /proc/<pid>/psinfo                     */
1760         pr_read_lpsinfo_32,     /* /proc/<pid>/lpsinfo                    */
1761         pr_read_map_32,         /* /proc/<pid>/map                        */
1762         pr_read_rmap_32,        /* /proc/<pid>/rmap                       */
1763         pr_read_xmap_32,        /* /proc/<pid>/xmap                       */
1764         pr_read_cred,           /* /proc/<pid>/cred                       */
1765         pr_read_sigact_32,      /* /proc/<pid>/sigact                     */
1766         pr_read_auxv_32,        /* /proc/<pid>/auxv                       */
1767 #if defined(__x86)
1768         pr_read_ldt,            /* /proc/<pid>/ldt                        */
1769 #endif
1770         pr_read_usage_32,       /* /proc/<pid>/usage                      */
1771         pr_read_lusage_32,      /* /proc/<pid>/lusage                     */
1772         pr_read_pagedata_32,    /* /proc/<pid>/pagedata                   */
1773         pr_read_watch_32,       /* /proc/<pid>/watch                      */
1774         pr_read_inval,          /* /proc/<pid>/cwd                        */
1775         pr_read_inval,          /* /proc/<pid>/root                       */
1776         pr_read_inval,          /* /proc/<pid>/fd                 */
1777         pr_read_inval,          /* /proc/<pid>/fd/nn                      */
1778         pr_read_inval,          /* /proc/<pid>/object                     */
1779         pr_read_inval,          /* /proc/<pid>/object/xxx         */
1780         pr_read_inval,          /* /proc/<pid>/lwp                        */
1781         pr_read_inval,          /* /proc/<pid>/lwp/<lwpid>          */
1782         pr_read_inval,          /* /proc/<pid>/lwp/<lwpid>/lwpctl   */
1783         pr_read_lwpstatus_32,   /* /proc/<pid>/lwp/<lwpid>/lwpstatus        */
1784         pr_read_lwpsinfo_32,    /* /proc/<pid>/lwp/<lwpid>/lwpsinfo */
1785         pr_read_lwpusage_32,    /* /proc/<pid>/lwp/<lwpid>/lwpusage */
1786         pr_read_xregs,          /* /proc/<pid>/lwp/<lwpid>/xregs    */
1787         pr_read_inval,          /* /proc/<pid>/lwp/<lwpid>/templates        */
1788         pr_read_inval,          /* /proc/<pid>/lwp/<lwpid>/templates/<id> */
1789         pr_read_spymaster_32,   /* /proc/<pid>/lwp/<lwpid>/spymaster        */
 
2669 {
2670         prnode_t *pnp = VTOP(vp);
2671 
2672         ASSERT(pnp->pr_type < PR_NFILES);
2673 
2674 #ifdef _SYSCALL32_IMPL
2675         /*
2676          * What is read from the /proc files depends on the data
2677          * model of the caller.  An LP64 process will see LP64
2678          * data.  An ILP32 process will see ILP32 data.
2679          */
2680         if (curproc->p_model == DATAMODEL_LP64)
2681                 return (pr_read_function[pnp->pr_type](pnp, uiop));
2682         else
2683                 return (pr_read_function_32[pnp->pr_type](pnp, uiop));
2684 #else
2685         return (pr_read_function[pnp->pr_type](pnp, uiop));
2686 #endif
2687 }
2688 
2689 /* ARGSUSED */
2690 static int
2691 prwrite(vnode_t *vp, uio_t *uiop, int ioflag, cred_t *cr, caller_context_t *ct)
2692 {
2693         prnode_t *pnp = VTOP(vp);
2694         int old = 0;
2695         int error;
2696         ssize_t resid;
2697 
2698         ASSERT(pnp->pr_type < PR_NFILES);
2699 
2700         /*
2701          * Only a handful of /proc files are writable, enumerate them here.
2702          */
2703         switch (pnp->pr_type) {
2704         case PR_PIDDIR:         /* directory write()s: visceral revulsion. */
2705                 ASSERT(pnp->pr_pidfile != NULL);
2706                 /* use the underlying PR_PIDFILE to write the process */
2707                 vp = pnp->pr_pidfile;
2708                 pnp = VTOP(vp);
 
2747                  * Perform the action on the control file
2748                  * by passing curthreads credentials
2749                  * and not target process's credentials.
2750                  */
2751 #ifdef _SYSCALL32_IMPL
2752                 if (curproc->p_model == DATAMODEL_ILP32)
2753                         error = prwritectl32(vp, uiop, CRED());
2754                 else
2755                         error = prwritectl(vp, uiop, CRED());
2756 #else
2757                 error = prwritectl(vp, uiop, CRED());
2758 #endif
2759                 /*
2760                  * This hack makes sure that the EINTR is passed
2761                  * all the way back to the caller's write() call.
2762                  */
2763                 if (error == EINTR)
2764                         uiop->uio_resid = resid;
2765                 return (error);
2766 
2767         default:
2768                 return ((vp->v_type == VDIR)? EISDIR : EBADF);
2769         }
2770         /* NOTREACHED */
2771 }
2772 
2773 static int
2774 prgetattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr,
2775         caller_context_t *ct)
2776 {
2777         prnode_t *pnp = VTOP(vp);
2778         prnodetype_t type = pnp->pr_type;
2779         prcommon_t *pcp;
2780         proc_t *p;
2781         struct as *as;
2782         int error;
2783         vnode_t *rvp;
2784         timestruc_t now;
2785         extern uint_t nproc;
2786         int ngroups;
 
3030                 break;
3031         case PR_CRED:
3032                 mutex_enter(&p->p_crlock);
3033                 vap->va_size = sizeof (prcred_t);
3034                 ngroups = crgetngroups(p->p_cred);
3035                 if (ngroups > 1)
3036                         vap->va_size += (ngroups - 1) * sizeof (gid_t);
3037                 mutex_exit(&p->p_crlock);
3038                 break;
3039         case PR_PRIV:
3040                 vap->va_size = prgetprivsize();
3041                 break;
3042         case PR_SIGACT:
3043                 nsig = PROC_IS_BRANDED(curproc)? BROP(curproc)->b_nsig : NSIG;
3044                 vap->va_size = (nsig-1) *
3045                     PR_OBJSIZE(struct sigaction32, struct sigaction);
3046                 break;
3047         case PR_AUXV:
3048                 vap->va_size = __KERN_NAUXV_IMPL * PR_OBJSIZE(auxv32_t, auxv_t);
3049                 break;
3050 #if defined(__x86)
3051         case PR_LDT:
3052                 mutex_exit(&p->p_lock);
3053                 mutex_enter(&p->p_ldtlock);
3054                 vap->va_size = prnldt(p) * sizeof (struct ssd);
3055                 mutex_exit(&p->p_ldtlock);
3056                 mutex_enter(&p->p_lock);
3057                 break;
3058 #endif
3059         case PR_USAGE:
3060                 vap->va_size = PR_OBJSIZE(prusage32_t, prusage_t);
3061                 break;
3062         case PR_LUSAGE:
3063                 vap->va_size = PR_OBJSIZE(prheader32_t, prheader_t) +
3064                     (p->p_lwpcnt + 1) * PR_OBJSPAN(prusage32_t, prusage_t);
3065                 break;
3066         case PR_PAGEDATA:
3067                 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas)
3068                         vap->va_size = 0;
3069                 else {
 
3205                  * Disallow access to fds with other than existing open modes.
3206                  */
3207                 rvp = pnp->pr_realvp;
3208                 vtype = rvp->v_type;
3209                 vmode = pnp->pr_mode;
3210                 if ((type == PR_OBJECT && (mode & VWRITE)) ||
3211                     (type == PR_FD && vtype != VREG && vtype != VDIR) ||
3212                     (type == PR_FD && (vmode & mode) != mode &&
3213                     secpolicy_proc_access(cr) != 0))
3214                         return (EACCES);
3215                 return (VOP_ACCESS(rvp, mode, flags, cr, ct));
3216 
3217         case PR_PSINFO:         /* these files can be read by anyone */
3218         case PR_LPSINFO:
3219         case PR_LWPSINFO:
3220         case PR_LWPDIR:
3221         case PR_LWPIDDIR:
3222         case PR_USAGE:
3223         case PR_LUSAGE:
3224         case PR_LWPUSAGE:
3225                 p = pr_p_lock(pnp);
3226                 mutex_exit(&pr_pidlock);
3227                 if (p == NULL)
3228                         return (ENOENT);
3229                 prunlock(pnp);
3230                 break;
3231 
3232         default:
3233                 /*
3234                  * Except for the world-readable files above,
3235                  * only /proc/pid exists if the process is a zombie.
3236                  */
3237                 if ((error = prlock(pnp,
3238                     (type == PR_PIDDIR)? ZYES : ZNO)) != 0)
3239                         return (error);
3240                 p = pnp->pr_common->prc_proc;
3241                 if (p != curproc)
3242                         error = priv_proc_cred_perm(cr, p, NULL, mode);
3243 
3244                 if (error != 0 || p == curproc || (p->p_flag & SSYS) ||
 
 
3290 
3291 static vnode_t *(*pr_lookup_function[PR_NFILES])() = {
3292         pr_lookup_procdir,      /* /proc                                */
3293         pr_lookup_notdir,       /* /proc/self                           */
3294         pr_lookup_piddir,       /* /proc/<pid>                            */
3295         pr_lookup_notdir,       /* /proc/<pid>/as                 */
3296         pr_lookup_notdir,       /* /proc/<pid>/ctl                        */
3297         pr_lookup_notdir,       /* /proc/<pid>/status                     */
3298         pr_lookup_notdir,       /* /proc/<pid>/lstatus                    */
3299         pr_lookup_notdir,       /* /proc/<pid>/psinfo                     */
3300         pr_lookup_notdir,       /* /proc/<pid>/lpsinfo                    */
3301         pr_lookup_notdir,       /* /proc/<pid>/map                        */
3302         pr_lookup_notdir,       /* /proc/<pid>/rmap                       */
3303         pr_lookup_notdir,       /* /proc/<pid>/xmap                       */
3304         pr_lookup_notdir,       /* /proc/<pid>/cred                       */
3305         pr_lookup_notdir,       /* /proc/<pid>/sigact                     */
3306         pr_lookup_notdir,       /* /proc/<pid>/auxv                       */
3307 #if defined(__x86)
3308         pr_lookup_notdir,       /* /proc/<pid>/ldt                        */
3309 #endif
3310         pr_lookup_notdir,       /* /proc/<pid>/usage                      */
3311         pr_lookup_notdir,       /* /proc/<pid>/lusage                     */
3312         pr_lookup_notdir,       /* /proc/<pid>/pagedata                   */
3313         pr_lookup_notdir,       /* /proc/<pid>/watch                      */
3314         pr_lookup_notdir,       /* /proc/<pid>/cwd                        */
3315         pr_lookup_notdir,       /* /proc/<pid>/root                       */
3316         pr_lookup_fddir,        /* /proc/<pid>/fd                 */
3317         pr_lookup_notdir,       /* /proc/<pid>/fd/nn                      */
3318         pr_lookup_objectdir,    /* /proc/<pid>/object                     */
3319         pr_lookup_notdir,       /* /proc/<pid>/object/xxx         */
3320         pr_lookup_lwpdir,       /* /proc/<pid>/lwp                        */
3321         pr_lookup_lwpiddir,     /* /proc/<pid>/lwp/<lwpid>          */
3322         pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/lwpctl   */
3323         pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/lwpstatus        */
3324         pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/lwpsinfo */
3325         pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/lwpusage */
3326         pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/xregs    */
3327         pr_lookup_tmpldir,      /* /proc/<pid>/lwp/<lwpid>/templates        */
3328         pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/templates/<id> */
3329         pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/spymaster        */
 
4529                 vp->v_type = VDIR;
4530                 pnp->pr_mode = 0555; /* read-search by all */
4531                 break;
4532 
4533         case PR_AS:
4534         case PR_TMPL:
4535                 pnp->pr_mode = 0600; /* read-write by owner only */
4536                 break;
4537 
4538         case PR_CTL:
4539         case PR_LWPCTL:
4540                 pnp->pr_mode = 0200; /* write-only by owner only */
4541                 break;
4542 
4543         case PR_PIDFILE:
4544         case PR_LWPIDFILE:
4545                 pnp->pr_mode = 0600; /* read-write by owner only */
4546                 break;
4547 
4548         case PR_PSINFO:
4549         case PR_LPSINFO:
4550         case PR_LWPSINFO:
4551         case PR_USAGE:
4552         case PR_LUSAGE:
4553         case PR_LWPUSAGE:
4554                 pnp->pr_mode = 0444; /* read-only by all */
4555                 break;
4556 
4557         default:
4558                 pnp->pr_mode = 0400; /* read-only by owner only */
4559                 break;
4560         }
4561         vn_exists(vp);
4562         return (pnp);
4563 }
4564 
4565 /*
4566  * Free the storage obtained from prgetnode().
4567  */
4568 void
4569 prfreenode(prnode_t *pnp)
4570 {
4571         vnode_t *vp;
4572         ulong_t nfiles;
4573 
 
4639 
4640 static int (*pr_readdir_function[PR_NFILES])() = {
4641         pr_readdir_procdir,     /* /proc                                */
4642         pr_readdir_notdir,      /* /proc/self                           */
4643         pr_readdir_piddir,      /* /proc/<pid>                            */
4644         pr_readdir_notdir,      /* /proc/<pid>/as                 */
4645         pr_readdir_notdir,      /* /proc/<pid>/ctl                        */
4646         pr_readdir_notdir,      /* /proc/<pid>/status                     */
4647         pr_readdir_notdir,      /* /proc/<pid>/lstatus                    */
4648         pr_readdir_notdir,      /* /proc/<pid>/psinfo                     */
4649         pr_readdir_notdir,      /* /proc/<pid>/lpsinfo                    */
4650         pr_readdir_notdir,      /* /proc/<pid>/map                        */
4651         pr_readdir_notdir,      /* /proc/<pid>/rmap                       */
4652         pr_readdir_notdir,      /* /proc/<pid>/xmap                       */
4653         pr_readdir_notdir,      /* /proc/<pid>/cred                       */
4654         pr_readdir_notdir,      /* /proc/<pid>/sigact                     */
4655         pr_readdir_notdir,      /* /proc/<pid>/auxv                       */
4656 #if defined(__x86)
4657         pr_readdir_notdir,      /* /proc/<pid>/ldt                        */
4658 #endif
4659         pr_readdir_notdir,      /* /proc/<pid>/usage                      */
4660         pr_readdir_notdir,      /* /proc/<pid>/lusage                     */
4661         pr_readdir_notdir,      /* /proc/<pid>/pagedata                   */
4662         pr_readdir_notdir,      /* /proc/<pid>/watch                      */
4663         pr_readdir_notdir,      /* /proc/<pid>/cwd                        */
4664         pr_readdir_notdir,      /* /proc/<pid>/root                       */
4665         pr_readdir_fddir,       /* /proc/<pid>/fd                 */
4666         pr_readdir_notdir,      /* /proc/<pid>/fd/nn                      */
4667         pr_readdir_objectdir,   /* /proc/<pid>/object                     */
4668         pr_readdir_notdir,      /* /proc/<pid>/object/xxx         */
4669         pr_readdir_lwpdir,      /* /proc/<pid>/lwp                        */
4670         pr_readdir_lwpiddir,    /* /proc/<pid>/lwp/<lwpid>          */
4671         pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/lwpctl   */
4672         pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/lwpstatus        */
4673         pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/lwpsinfo */
4674         pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/lwpusage */
4675         pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/xregs    */
4676         pr_readdir_tmpldir,     /* /proc/<pid>/lwp/<lwpid>/templates        */
4677         pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/templates/<id> */
4678         pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/spymaster        */
 
4788         if (pnp->pr_pcommon->prc_proc == NULL)
4789                 return (ENOENT);
4790         if (uiop->uio_offset >= sizeof (piddir))
4791                 goto out;
4792 
4793         /*
4794          * Loop until user's request is satisfied, omitting some
4795          * files along the way if the process is a zombie.
4796          */
4797         for (dirp = &piddir[uiop->uio_offset / sizeof (prdirent_t)];
4798             uiop->uio_resid >= sizeof (prdirent_t) &&
4799             dirp < &piddir[NPIDDIRFILES+2];
4800             uiop->uio_offset = off + sizeof (prdirent_t), dirp++) {
4801                 off = uiop->uio_offset;
4802                 if (zombie) {
4803                         switch (dirp->d_ino) {
4804                         case PR_PIDDIR:
4805                         case PR_PROCDIR:
4806                         case PR_PSINFO:
4807                         case PR_USAGE:
4808                                 break;
4809                         default:
4810                                 continue;
4811                         }
4812                 }
4813                 bcopy(dirp, &dirent, sizeof (prdirent_t));
4814                 if (dirent.d_ino == PR_PROCDIR)
4815                         dirent.d_ino = PRROOTINO;
4816                 else
4817                         dirent.d_ino = pmkino(0, pnp->pr_pcommon->prc_slot,
4818                             dirent.d_ino);
4819                 if ((error = uiomove((caddr_t)&dirent, sizeof (prdirent_t),
4820                     UIO_READ, uiop)) != 0)
4821                         return (error);
4822         }
4823 out:
4824         if (eofp)
4825                 *eofp = (uiop->uio_offset >= sizeof (piddir));
4826         return (0);
4827 }
 
 | 
 
 
   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 2015, Joyent, Inc.
  25  */
  26 
  27 /*      Copyright (c) 1984,      1986, 1987, 1988, 1989 AT&T        */
  28 /*        All Rights Reserved   */
  29 
  30 #include <sys/types.h>
  31 #include <sys/param.h>
  32 #include <sys/time.h>
  33 #include <sys/cred.h>
  34 #include <sys/policy.h>
  35 #include <sys/debug.h>
  36 #include <sys/dirent.h>
  37 #include <sys/errno.h>
  38 #include <sys/file.h>
  39 #include <sys/inline.h>
  40 #include <sys/kmem.h>
  41 #include <sys/pathname.h>
  42 #include <sys/proc.h>
  43 #include <sys/brand.h>
  44 #include <sys/signal.h>
 
 
  79 
  80 /*
  81  * Created by prinit.
  82  */
  83 vnodeops_t *prvnodeops;
  84 
  85 /*
  86  * Directory characteristics (patterned after the s5 file system).
  87  */
  88 #define PRROOTINO       2
  89 
  90 #define PRDIRSIZE       14
  91 struct prdirect {
  92         ushort_t        d_ino;
  93         char            d_name[PRDIRSIZE];
  94 };
  95 
  96 #define PRSDSIZE        (sizeof (struct prdirect))
  97 
  98 /*
  99  * Maximum length of the /proc/$$/argv file:
 100  */
 101 int prmaxargvlen = 4096;
 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" },
 
 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_OBJECTDIR, 22 * sizeof (prdirent_t), sizeof (prdirent_t),
 161                 "object" },
 162         { PR_LWPDIR,    23 * sizeof (prdirent_t), sizeof (prdirent_t),
 163                 "lwp" },
 164         { PR_PRIV,      24 * sizeof (prdirent_t), sizeof (prdirent_t),
 165                 "priv" },
 166         { PR_PATHDIR,   25 * sizeof (prdirent_t), sizeof (prdirent_t),
 167                 "path" },
 168         { PR_CTDIR,     26 * sizeof (prdirent_t), sizeof (prdirent_t),
 169                 "contracts" },
 170 #if defined(__x86)
 171         { PR_LDT,       27 * sizeof (prdirent_t), sizeof (prdirent_t),
 172                 "ldt" },
 173 #endif
 174         { PR_ARGV,      28 * sizeof (prdirent_t), sizeof (prdirent_t),
 175                 "argv" },
 176 };
 177 
 178 #define NPIDDIRFILES    (sizeof (piddir) / sizeof (piddir[0]) - 2)
 179 
 180 /*
 181  * Contents of a /proc/<pid>/lwp/<lwpid> directory.
 182  */
 183 static prdirent_t lwpiddir[] = {
 184         { PR_LWPIDDIR,   1 * sizeof (prdirent_t), sizeof (prdirent_t),
 185                 "." },
 186         { PR_LWPDIR,     2 * sizeof (prdirent_t), sizeof (prdirent_t),
 187                 ".." },
 188         { PR_LWPCTL,     3 * sizeof (prdirent_t), sizeof (prdirent_t),
 189                 "lwpctl" },
 190         { PR_LWPSTATUS,  4 * sizeof (prdirent_t), sizeof (prdirent_t),
 191                 "lwpstatus" },
 192         { PR_LWPSINFO,   5 * sizeof (prdirent_t), sizeof (prdirent_t),
 193                 "lwpsinfo" },
 194         { PR_LWPUSAGE,   6 * sizeof (prdirent_t), sizeof (prdirent_t),
 195                 "lwpusage" },
 
 572                 if (killproc)
 573                         sigtoproc(p, NULL, SIGKILL);
 574                 else
 575                         allsetrun(p);
 576         }
 577 
 578         prunlock(pnp);
 579         return (0);
 580 }
 581 
 582 /*
 583  * Array of read functions, indexed by /proc file type.
 584  */
 585 static int pr_read_inval(), pr_read_as(), pr_read_status(),
 586         pr_read_lstatus(), pr_read_psinfo(), pr_read_lpsinfo(),
 587         pr_read_map(), pr_read_rmap(), pr_read_xmap(),
 588         pr_read_cred(), pr_read_sigact(), pr_read_auxv(),
 589 #if defined(__x86)
 590         pr_read_ldt(),
 591 #endif
 592         pr_read_argv(),
 593         pr_read_usage(), pr_read_lusage(), pr_read_pagedata(),
 594         pr_read_watch(), pr_read_lwpstatus(), pr_read_lwpsinfo(),
 595         pr_read_lwpusage(), pr_read_xregs(), pr_read_priv(),
 596         pr_read_spymaster(),
 597 #if defined(__sparc)
 598         pr_read_gwindows(), pr_read_asrs(),
 599 #endif
 600         pr_read_piddir(), pr_read_pidfile(), pr_read_opagedata();
 601 
 602 static int (*pr_read_function[PR_NFILES])() = {
 603         pr_read_inval,          /* /proc                                */
 604         pr_read_inval,          /* /proc/self                           */
 605         pr_read_piddir,         /* /proc/<pid> (old /proc read()) */
 606         pr_read_as,             /* /proc/<pid>/as                 */
 607         pr_read_inval,          /* /proc/<pid>/ctl                        */
 608         pr_read_status,         /* /proc/<pid>/status                     */
 609         pr_read_lstatus,        /* /proc/<pid>/lstatus                    */
 610         pr_read_psinfo,         /* /proc/<pid>/psinfo                     */
 611         pr_read_lpsinfo,        /* /proc/<pid>/lpsinfo                    */
 612         pr_read_map,            /* /proc/<pid>/map                        */
 613         pr_read_rmap,           /* /proc/<pid>/rmap                       */
 614         pr_read_xmap,           /* /proc/<pid>/xmap                       */
 615         pr_read_cred,           /* /proc/<pid>/cred                       */
 616         pr_read_sigact,         /* /proc/<pid>/sigact                     */
 617         pr_read_auxv,           /* /proc/<pid>/auxv                       */
 618 #if defined(__x86)
 619         pr_read_ldt,            /* /proc/<pid>/ldt                        */
 620 #endif
 621         pr_read_argv,           /* /proc/<pid>/argv                       */
 622         pr_read_usage,          /* /proc/<pid>/usage                      */
 623         pr_read_lusage,         /* /proc/<pid>/lusage                     */
 624         pr_read_pagedata,       /* /proc/<pid>/pagedata                   */
 625         pr_read_watch,          /* /proc/<pid>/watch                      */
 626         pr_read_inval,          /* /proc/<pid>/cwd                        */
 627         pr_read_inval,          /* /proc/<pid>/root                       */
 628         pr_read_inval,          /* /proc/<pid>/fd                 */
 629         pr_read_inval,          /* /proc/<pid>/fd/nn                      */
 630         pr_read_inval,          /* /proc/<pid>/object                     */
 631         pr_read_inval,          /* /proc/<pid>/object/xxx         */
 632         pr_read_inval,          /* /proc/<pid>/lwp                        */
 633         pr_read_inval,          /* /proc/<pid>/lwp/<lwpid>          */
 634         pr_read_inval,          /* /proc/<pid>/lwp/<lwpid>/lwpctl   */
 635         pr_read_lwpstatus,      /* /proc/<pid>/lwp/<lwpid>/lwpstatus        */
 636         pr_read_lwpsinfo,       /* /proc/<pid>/lwp/<lwpid>/lwpsinfo */
 637         pr_read_lwpusage,       /* /proc/<pid>/lwp/<lwpid>/lwpusage */
 638         pr_read_xregs,          /* /proc/<pid>/lwp/<lwpid>/xregs    */
 639         pr_read_inval,          /* /proc/<pid>/lwp/<lwpid>/templates        */
 640         pr_read_inval,          /* /proc/<pid>/lwp/<lwpid>/templates/<id> */
 641         pr_read_spymaster,      /* /proc/<pid>/lwp/<lwpid>/spymaster        */
 
 664          */
 665         return (EINVAL);
 666 }
 667 
 668 static int
 669 pr_uioread(void *base, long count, uio_t *uiop)
 670 {
 671         int error = 0;
 672 
 673         ASSERT(count >= 0);
 674         count -= uiop->uio_offset;
 675         if (count > 0 && uiop->uio_offset >= 0) {
 676                 error = uiomove((char *)base + uiop->uio_offset,
 677                     count, UIO_READ, uiop);
 678         }
 679 
 680         return (error);
 681 }
 682 
 683 static int
 684 pr_read_argv(prnode_t *pnp, uio_t *uiop)
 685 {
 686         char *args;
 687         int error;
 688         size_t asz = prmaxargvlen, sz;
 689 
 690         /*
 691          * Allocate a scratch buffer for collection of the process arguments.
 692          */
 693         args = kmem_alloc(asz, KM_SLEEP);
 694 
 695         ASSERT(pnp->pr_type == PR_ARGV);
 696 
 697         if ((error = prlock(pnp, ZNO)) != 0) {
 698                 kmem_free(args, asz);
 699                 return (error);
 700         }
 701 
 702         if ((error = prreadargv(pnp->pr_common->prc_proc, args, asz,
 703             &sz)) != 0) {
 704                 prunlock(pnp);
 705                 kmem_free(args, asz);
 706                 return (error);
 707         }
 708 
 709         prunlock(pnp);
 710 
 711         error = pr_uioread(args, sz, uiop);
 712 
 713         kmem_free(args, asz);
 714 
 715         return (error);
 716 }
 717 
 718 static int
 719 pr_read_as(prnode_t *pnp, uio_t *uiop)
 720 {
 721         int error;
 722 
 723         ASSERT(pnp->pr_type == PR_AS);
 724 
 725         if ((error = prlock(pnp, ZNO)) == 0) {
 726                 proc_t *p = pnp->pr_common->prc_proc;
 727                 struct as *as = p->p_as;
 728 
 729                 /*
 730                  * /proc I/O cannot be done to a system process.
 731                  * A 32-bit process cannot read a 64-bit process.
 732                  */
 733                 if ((p->p_flag & SSYS) || as == &kas) {
 734                         error = 0;
 735 #ifdef _SYSCALL32_IMPL
 736                 } else if (curproc->p_model == DATAMODEL_ILP32 &&
 737                     PROCESS_NOT_32BIT(p)) {
 738                         error = EOVERFLOW;
 
1794 
1795 static int (*pr_read_function_32[PR_NFILES])() = {
1796         pr_read_inval,          /* /proc                                */
1797         pr_read_inval,          /* /proc/self                           */
1798         pr_read_piddir,         /* /proc/<pid> (old /proc read()) */
1799         pr_read_as,             /* /proc/<pid>/as                 */
1800         pr_read_inval,          /* /proc/<pid>/ctl                        */
1801         pr_read_status_32,      /* /proc/<pid>/status                     */
1802         pr_read_lstatus_32,     /* /proc/<pid>/lstatus                    */
1803         pr_read_psinfo_32,      /* /proc/<pid>/psinfo                     */
1804         pr_read_lpsinfo_32,     /* /proc/<pid>/lpsinfo                    */
1805         pr_read_map_32,         /* /proc/<pid>/map                        */
1806         pr_read_rmap_32,        /* /proc/<pid>/rmap                       */
1807         pr_read_xmap_32,        /* /proc/<pid>/xmap                       */
1808         pr_read_cred,           /* /proc/<pid>/cred                       */
1809         pr_read_sigact_32,      /* /proc/<pid>/sigact                     */
1810         pr_read_auxv_32,        /* /proc/<pid>/auxv                       */
1811 #if defined(__x86)
1812         pr_read_ldt,            /* /proc/<pid>/ldt                        */
1813 #endif
1814         pr_read_argv,           /* /proc/<pid>/argv                       */
1815         pr_read_usage_32,       /* /proc/<pid>/usage                      */
1816         pr_read_lusage_32,      /* /proc/<pid>/lusage                     */
1817         pr_read_pagedata_32,    /* /proc/<pid>/pagedata                   */
1818         pr_read_watch_32,       /* /proc/<pid>/watch                      */
1819         pr_read_inval,          /* /proc/<pid>/cwd                        */
1820         pr_read_inval,          /* /proc/<pid>/root                       */
1821         pr_read_inval,          /* /proc/<pid>/fd                 */
1822         pr_read_inval,          /* /proc/<pid>/fd/nn                      */
1823         pr_read_inval,          /* /proc/<pid>/object                     */
1824         pr_read_inval,          /* /proc/<pid>/object/xxx         */
1825         pr_read_inval,          /* /proc/<pid>/lwp                        */
1826         pr_read_inval,          /* /proc/<pid>/lwp/<lwpid>          */
1827         pr_read_inval,          /* /proc/<pid>/lwp/<lwpid>/lwpctl   */
1828         pr_read_lwpstatus_32,   /* /proc/<pid>/lwp/<lwpid>/lwpstatus        */
1829         pr_read_lwpsinfo_32,    /* /proc/<pid>/lwp/<lwpid>/lwpsinfo */
1830         pr_read_lwpusage_32,    /* /proc/<pid>/lwp/<lwpid>/lwpusage */
1831         pr_read_xregs,          /* /proc/<pid>/lwp/<lwpid>/xregs    */
1832         pr_read_inval,          /* /proc/<pid>/lwp/<lwpid>/templates        */
1833         pr_read_inval,          /* /proc/<pid>/lwp/<lwpid>/templates/<id> */
1834         pr_read_spymaster_32,   /* /proc/<pid>/lwp/<lwpid>/spymaster        */
 
2714 {
2715         prnode_t *pnp = VTOP(vp);
2716 
2717         ASSERT(pnp->pr_type < PR_NFILES);
2718 
2719 #ifdef _SYSCALL32_IMPL
2720         /*
2721          * What is read from the /proc files depends on the data
2722          * model of the caller.  An LP64 process will see LP64
2723          * data.  An ILP32 process will see ILP32 data.
2724          */
2725         if (curproc->p_model == DATAMODEL_LP64)
2726                 return (pr_read_function[pnp->pr_type](pnp, uiop));
2727         else
2728                 return (pr_read_function_32[pnp->pr_type](pnp, uiop));
2729 #else
2730         return (pr_read_function[pnp->pr_type](pnp, uiop));
2731 #endif
2732 }
2733 
2734 /*
2735  * We make pr_write_psinfo_fname() somewhat simpler by asserting at compile
2736  * time that PRFNSZ has the same definition as MAXCOMLEN.
2737  */
2738 #if PRFNSZ != MAXCOMLEN
2739 #error PRFNSZ/MAXCOMLEN mismatch
2740 #endif
2741 
2742 static int
2743 pr_write_psinfo_fname(prnode_t *pnp, uio_t *uiop)
2744 {
2745         char fname[PRFNSZ];
2746         int offset = offsetof(psinfo_t, pr_fname), error;
2747 
2748 #ifdef _SYSCALL32_IMPL
2749         if (curproc->p_model != DATAMODEL_LP64)
2750                 offset = offsetof(psinfo32_t, pr_fname);
2751 #endif
2752 
2753         /*
2754          * If this isn't a write to pr_fname (or if the size doesn't match
2755          * PRFNSZ) return.
2756          */
2757         if (uiop->uio_offset != offset || uiop->uio_resid != PRFNSZ)
2758                 return (0);
2759 
2760         if ((error = uiomove(fname, PRFNSZ, UIO_WRITE, uiop)) != 0)
2761                 return (error);
2762 
2763         fname[PRFNSZ - 1] = '\0';
2764 
2765         if ((error = prlock(pnp, ZNO)) != 0)
2766                 return (error);
2767 
2768         bcopy(fname, pnp->pr_common->prc_proc->p_user.u_comm, PRFNSZ);
2769 
2770         prunlock(pnp);
2771 
2772         return (0);
2773 }
2774 
2775 /*
2776  * We make pr_write_psinfo_psargs() somewhat simpler by asserting at compile
2777  * time that PRARGSZ has the same definition as PSARGSZ.
2778  */
2779 #if PRARGSZ != PSARGSZ
2780 #error PRARGSZ/PSARGSZ mismatch
2781 #endif
2782 
2783 static int
2784 pr_write_psinfo_psargs(prnode_t *pnp, uio_t *uiop)
2785 {
2786         char psargs[PRARGSZ];
2787         int offset = offsetof(psinfo_t, pr_psargs), error;
2788 
2789 #ifdef _SYSCALL32_IMPL
2790         if (curproc->p_model != DATAMODEL_LP64)
2791                 offset = offsetof(psinfo32_t, pr_psargs);
2792 #endif
2793 
2794         /*
2795          * If this isn't a write to pr_psargs (or if the size doesn't match
2796          * PRARGSZ) return.
2797          */
2798         if (uiop->uio_offset != offset || uiop->uio_resid != PRARGSZ)
2799                 return (0);
2800 
2801         if ((error = uiomove(psargs, PRARGSZ, UIO_WRITE, uiop)) != 0)
2802                 return (error);
2803 
2804         psargs[PRARGSZ - 1] = '\0';
2805 
2806         if ((error = prlock(pnp, ZNO)) != 0)
2807                 return (error);
2808 
2809         bcopy(psargs, pnp->pr_common->prc_proc->p_user.u_psargs, PRARGSZ);
2810 
2811         prunlock(pnp);
2812 
2813         return (0);
2814 }
2815 
2816 int
2817 pr_write_psinfo(prnode_t *pnp, uio_t *uiop)
2818 {
2819         int error;
2820 
2821         if ((error = pr_write_psinfo_fname(pnp, uiop)) != 0)
2822                 return (error);
2823 
2824         if ((error = pr_write_psinfo_psargs(pnp, uiop)) != 0)
2825                 return (error);
2826 
2827         return (0);
2828 }
2829 
2830 
2831 /* ARGSUSED */
2832 static int
2833 prwrite(vnode_t *vp, uio_t *uiop, int ioflag, cred_t *cr, caller_context_t *ct)
2834 {
2835         prnode_t *pnp = VTOP(vp);
2836         int old = 0;
2837         int error;
2838         ssize_t resid;
2839 
2840         ASSERT(pnp->pr_type < PR_NFILES);
2841 
2842         /*
2843          * Only a handful of /proc files are writable, enumerate them here.
2844          */
2845         switch (pnp->pr_type) {
2846         case PR_PIDDIR:         /* directory write()s: visceral revulsion. */
2847                 ASSERT(pnp->pr_pidfile != NULL);
2848                 /* use the underlying PR_PIDFILE to write the process */
2849                 vp = pnp->pr_pidfile;
2850                 pnp = VTOP(vp);
 
2889                  * Perform the action on the control file
2890                  * by passing curthreads credentials
2891                  * and not target process's credentials.
2892                  */
2893 #ifdef _SYSCALL32_IMPL
2894                 if (curproc->p_model == DATAMODEL_ILP32)
2895                         error = prwritectl32(vp, uiop, CRED());
2896                 else
2897                         error = prwritectl(vp, uiop, CRED());
2898 #else
2899                 error = prwritectl(vp, uiop, CRED());
2900 #endif
2901                 /*
2902                  * This hack makes sure that the EINTR is passed
2903                  * all the way back to the caller's write() call.
2904                  */
2905                 if (error == EINTR)
2906                         uiop->uio_resid = resid;
2907                 return (error);
2908 
2909         case PR_PSINFO:
2910                 return (pr_write_psinfo(pnp, uiop));
2911 
2912         default:
2913                 return ((vp->v_type == VDIR)? EISDIR : EBADF);
2914         }
2915         /* NOTREACHED */
2916 }
2917 
2918 static int
2919 prgetattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr,
2920         caller_context_t *ct)
2921 {
2922         prnode_t *pnp = VTOP(vp);
2923         prnodetype_t type = pnp->pr_type;
2924         prcommon_t *pcp;
2925         proc_t *p;
2926         struct as *as;
2927         int error;
2928         vnode_t *rvp;
2929         timestruc_t now;
2930         extern uint_t nproc;
2931         int ngroups;
 
3175                 break;
3176         case PR_CRED:
3177                 mutex_enter(&p->p_crlock);
3178                 vap->va_size = sizeof (prcred_t);
3179                 ngroups = crgetngroups(p->p_cred);
3180                 if (ngroups > 1)
3181                         vap->va_size += (ngroups - 1) * sizeof (gid_t);
3182                 mutex_exit(&p->p_crlock);
3183                 break;
3184         case PR_PRIV:
3185                 vap->va_size = prgetprivsize();
3186                 break;
3187         case PR_SIGACT:
3188                 nsig = PROC_IS_BRANDED(curproc)? BROP(curproc)->b_nsig : NSIG;
3189                 vap->va_size = (nsig-1) *
3190                     PR_OBJSIZE(struct sigaction32, struct sigaction);
3191                 break;
3192         case PR_AUXV:
3193                 vap->va_size = __KERN_NAUXV_IMPL * PR_OBJSIZE(auxv32_t, auxv_t);
3194                 break;
3195         case PR_ARGV:
3196                 if ((p->p_flag & SSYS) || p->p_as == &kas) {
3197                         vap->va_size = PSARGSZ;
3198                 } else {
3199                         vap->va_size = prmaxargvlen;
3200                 }
3201                 break;
3202 #if defined(__x86)
3203         case PR_LDT:
3204                 mutex_exit(&p->p_lock);
3205                 mutex_enter(&p->p_ldtlock);
3206                 vap->va_size = prnldt(p) * sizeof (struct ssd);
3207                 mutex_exit(&p->p_ldtlock);
3208                 mutex_enter(&p->p_lock);
3209                 break;
3210 #endif
3211         case PR_USAGE:
3212                 vap->va_size = PR_OBJSIZE(prusage32_t, prusage_t);
3213                 break;
3214         case PR_LUSAGE:
3215                 vap->va_size = PR_OBJSIZE(prheader32_t, prheader_t) +
3216                     (p->p_lwpcnt + 1) * PR_OBJSPAN(prusage32_t, prusage_t);
3217                 break;
3218         case PR_PAGEDATA:
3219                 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas)
3220                         vap->va_size = 0;
3221                 else {
 
3357                  * Disallow access to fds with other than existing open modes.
3358                  */
3359                 rvp = pnp->pr_realvp;
3360                 vtype = rvp->v_type;
3361                 vmode = pnp->pr_mode;
3362                 if ((type == PR_OBJECT && (mode & VWRITE)) ||
3363                     (type == PR_FD && vtype != VREG && vtype != VDIR) ||
3364                     (type == PR_FD && (vmode & mode) != mode &&
3365                     secpolicy_proc_access(cr) != 0))
3366                         return (EACCES);
3367                 return (VOP_ACCESS(rvp, mode, flags, cr, ct));
3368 
3369         case PR_PSINFO:         /* these files can be read by anyone */
3370         case PR_LPSINFO:
3371         case PR_LWPSINFO:
3372         case PR_LWPDIR:
3373         case PR_LWPIDDIR:
3374         case PR_USAGE:
3375         case PR_LUSAGE:
3376         case PR_LWPUSAGE:
3377         case PR_ARGV:
3378                 p = pr_p_lock(pnp);
3379                 mutex_exit(&pr_pidlock);
3380                 if (p == NULL)
3381                         return (ENOENT);
3382                 prunlock(pnp);
3383                 break;
3384 
3385         default:
3386                 /*
3387                  * Except for the world-readable files above,
3388                  * only /proc/pid exists if the process is a zombie.
3389                  */
3390                 if ((error = prlock(pnp,
3391                     (type == PR_PIDDIR)? ZYES : ZNO)) != 0)
3392                         return (error);
3393                 p = pnp->pr_common->prc_proc;
3394                 if (p != curproc)
3395                         error = priv_proc_cred_perm(cr, p, NULL, mode);
3396 
3397                 if (error != 0 || p == curproc || (p->p_flag & SSYS) ||
 
 
3443 
3444 static vnode_t *(*pr_lookup_function[PR_NFILES])() = {
3445         pr_lookup_procdir,      /* /proc                                */
3446         pr_lookup_notdir,       /* /proc/self                           */
3447         pr_lookup_piddir,       /* /proc/<pid>                            */
3448         pr_lookup_notdir,       /* /proc/<pid>/as                 */
3449         pr_lookup_notdir,       /* /proc/<pid>/ctl                        */
3450         pr_lookup_notdir,       /* /proc/<pid>/status                     */
3451         pr_lookup_notdir,       /* /proc/<pid>/lstatus                    */
3452         pr_lookup_notdir,       /* /proc/<pid>/psinfo                     */
3453         pr_lookup_notdir,       /* /proc/<pid>/lpsinfo                    */
3454         pr_lookup_notdir,       /* /proc/<pid>/map                        */
3455         pr_lookup_notdir,       /* /proc/<pid>/rmap                       */
3456         pr_lookup_notdir,       /* /proc/<pid>/xmap                       */
3457         pr_lookup_notdir,       /* /proc/<pid>/cred                       */
3458         pr_lookup_notdir,       /* /proc/<pid>/sigact                     */
3459         pr_lookup_notdir,       /* /proc/<pid>/auxv                       */
3460 #if defined(__x86)
3461         pr_lookup_notdir,       /* /proc/<pid>/ldt                        */
3462 #endif
3463         pr_lookup_notdir,       /* /proc/<pid>/argv                       */
3464         pr_lookup_notdir,       /* /proc/<pid>/usage                      */
3465         pr_lookup_notdir,       /* /proc/<pid>/lusage                     */
3466         pr_lookup_notdir,       /* /proc/<pid>/pagedata                   */
3467         pr_lookup_notdir,       /* /proc/<pid>/watch                      */
3468         pr_lookup_notdir,       /* /proc/<pid>/cwd                        */
3469         pr_lookup_notdir,       /* /proc/<pid>/root                       */
3470         pr_lookup_fddir,        /* /proc/<pid>/fd                 */
3471         pr_lookup_notdir,       /* /proc/<pid>/fd/nn                      */
3472         pr_lookup_objectdir,    /* /proc/<pid>/object                     */
3473         pr_lookup_notdir,       /* /proc/<pid>/object/xxx         */
3474         pr_lookup_lwpdir,       /* /proc/<pid>/lwp                        */
3475         pr_lookup_lwpiddir,     /* /proc/<pid>/lwp/<lwpid>          */
3476         pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/lwpctl   */
3477         pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/lwpstatus        */
3478         pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/lwpsinfo */
3479         pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/lwpusage */
3480         pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/xregs    */
3481         pr_lookup_tmpldir,      /* /proc/<pid>/lwp/<lwpid>/templates        */
3482         pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/templates/<id> */
3483         pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/spymaster        */
 
4683                 vp->v_type = VDIR;
4684                 pnp->pr_mode = 0555; /* read-search by all */
4685                 break;
4686 
4687         case PR_AS:
4688         case PR_TMPL:
4689                 pnp->pr_mode = 0600; /* read-write by owner only */
4690                 break;
4691 
4692         case PR_CTL:
4693         case PR_LWPCTL:
4694                 pnp->pr_mode = 0200; /* write-only by owner only */
4695                 break;
4696 
4697         case PR_PIDFILE:
4698         case PR_LWPIDFILE:
4699                 pnp->pr_mode = 0600; /* read-write by owner only */
4700                 break;
4701 
4702         case PR_PSINFO:
4703                 pnp->pr_mode = 0644; /* readable by all + owner can write */
4704                 break;
4705 
4706         case PR_LPSINFO:
4707         case PR_LWPSINFO:
4708         case PR_USAGE:
4709         case PR_LUSAGE:
4710         case PR_LWPUSAGE:
4711         case PR_ARGV:
4712                 pnp->pr_mode = 0444; /* read-only by all */
4713                 break;
4714 
4715         default:
4716                 pnp->pr_mode = 0400; /* read-only by owner only */
4717                 break;
4718         }
4719         vn_exists(vp);
4720         return (pnp);
4721 }
4722 
4723 /*
4724  * Free the storage obtained from prgetnode().
4725  */
4726 void
4727 prfreenode(prnode_t *pnp)
4728 {
4729         vnode_t *vp;
4730         ulong_t nfiles;
4731 
 
4797 
4798 static int (*pr_readdir_function[PR_NFILES])() = {
4799         pr_readdir_procdir,     /* /proc                                */
4800         pr_readdir_notdir,      /* /proc/self                           */
4801         pr_readdir_piddir,      /* /proc/<pid>                            */
4802         pr_readdir_notdir,      /* /proc/<pid>/as                 */
4803         pr_readdir_notdir,      /* /proc/<pid>/ctl                        */
4804         pr_readdir_notdir,      /* /proc/<pid>/status                     */
4805         pr_readdir_notdir,      /* /proc/<pid>/lstatus                    */
4806         pr_readdir_notdir,      /* /proc/<pid>/psinfo                     */
4807         pr_readdir_notdir,      /* /proc/<pid>/lpsinfo                    */
4808         pr_readdir_notdir,      /* /proc/<pid>/map                        */
4809         pr_readdir_notdir,      /* /proc/<pid>/rmap                       */
4810         pr_readdir_notdir,      /* /proc/<pid>/xmap                       */
4811         pr_readdir_notdir,      /* /proc/<pid>/cred                       */
4812         pr_readdir_notdir,      /* /proc/<pid>/sigact                     */
4813         pr_readdir_notdir,      /* /proc/<pid>/auxv                       */
4814 #if defined(__x86)
4815         pr_readdir_notdir,      /* /proc/<pid>/ldt                        */
4816 #endif
4817         pr_readdir_notdir,      /* /proc/<pid>/argv                       */
4818         pr_readdir_notdir,      /* /proc/<pid>/usage                      */
4819         pr_readdir_notdir,      /* /proc/<pid>/lusage                     */
4820         pr_readdir_notdir,      /* /proc/<pid>/pagedata                   */
4821         pr_readdir_notdir,      /* /proc/<pid>/watch                      */
4822         pr_readdir_notdir,      /* /proc/<pid>/cwd                        */
4823         pr_readdir_notdir,      /* /proc/<pid>/root                       */
4824         pr_readdir_fddir,       /* /proc/<pid>/fd                 */
4825         pr_readdir_notdir,      /* /proc/<pid>/fd/nn                      */
4826         pr_readdir_objectdir,   /* /proc/<pid>/object                     */
4827         pr_readdir_notdir,      /* /proc/<pid>/object/xxx         */
4828         pr_readdir_lwpdir,      /* /proc/<pid>/lwp                        */
4829         pr_readdir_lwpiddir,    /* /proc/<pid>/lwp/<lwpid>          */
4830         pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/lwpctl   */
4831         pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/lwpstatus        */
4832         pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/lwpsinfo */
4833         pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/lwpusage */
4834         pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/xregs    */
4835         pr_readdir_tmpldir,     /* /proc/<pid>/lwp/<lwpid>/templates        */
4836         pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/templates/<id> */
4837         pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/spymaster        */
 
4947         if (pnp->pr_pcommon->prc_proc == NULL)
4948                 return (ENOENT);
4949         if (uiop->uio_offset >= sizeof (piddir))
4950                 goto out;
4951 
4952         /*
4953          * Loop until user's request is satisfied, omitting some
4954          * files along the way if the process is a zombie.
4955          */
4956         for (dirp = &piddir[uiop->uio_offset / sizeof (prdirent_t)];
4957             uiop->uio_resid >= sizeof (prdirent_t) &&
4958             dirp < &piddir[NPIDDIRFILES+2];
4959             uiop->uio_offset = off + sizeof (prdirent_t), dirp++) {
4960                 off = uiop->uio_offset;
4961                 if (zombie) {
4962                         switch (dirp->d_ino) {
4963                         case PR_PIDDIR:
4964                         case PR_PROCDIR:
4965                         case PR_PSINFO:
4966                         case PR_USAGE:
4967                         case PR_ARGV:
4968                                 break;
4969                         default:
4970                                 continue;
4971                         }
4972                 }
4973                 bcopy(dirp, &dirent, sizeof (prdirent_t));
4974                 if (dirent.d_ino == PR_PROCDIR)
4975                         dirent.d_ino = PRROOTINO;
4976                 else
4977                         dirent.d_ino = pmkino(0, pnp->pr_pcommon->prc_slot,
4978                             dirent.d_ino);
4979                 if ((error = uiomove((caddr_t)&dirent, sizeof (prdirent_t),
4980                     UIO_READ, uiop)) != 0)
4981                         return (error);
4982         }
4983 out:
4984         if (eofp)
4985                 *eofp = (uiop->uio_offset >= sizeof (piddir));
4986         return (0);
4987 }
 
 |