Print this page
7029 want per-process exploit mitigation features (secflags)
7030 want basic address space layout randomization (aslr)
7031 noexec_user_stack should be a secflag
7032 want a means to forbid mappings around NULL.

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/proc/prvnops.c
          +++ new/usr/src/uts/common/fs/proc/prvnops.c
↓ open down ↓ 154 lines elided ↑ open up ↑
 155  155          { PR_OBJECTDIR, 22 * sizeof (prdirent_t), sizeof (prdirent_t),
 156  156                  "object" },
 157  157          { PR_LWPDIR,    23 * sizeof (prdirent_t), sizeof (prdirent_t),
 158  158                  "lwp" },
 159  159          { PR_PRIV,      24 * sizeof (prdirent_t), sizeof (prdirent_t),
 160  160                  "priv" },
 161  161          { PR_PATHDIR,   25 * sizeof (prdirent_t), sizeof (prdirent_t),
 162  162                  "path" },
 163  163          { PR_CTDIR,     26 * sizeof (prdirent_t), sizeof (prdirent_t),
 164  164                  "contracts" },
      165 +        { PR_SECFLAGS,  27 * sizeof (prdirent_t), sizeof (prdirent_t),
      166 +                "secflags" },
 165  167  #if defined(__x86)
 166      -        { PR_LDT,       27 * sizeof (prdirent_t), sizeof (prdirent_t),
      168 +        { PR_LDT,       28 * sizeof (prdirent_t), sizeof (prdirent_t),
 167  169                  "ldt" },
 168  170  #endif
 169  171  };
 170  172  
 171  173  #define NPIDDIRFILES    (sizeof (piddir) / sizeof (piddir[0]) - 2)
 172  174  
 173  175  /*
 174  176   * Contents of a /proc/<pid>/lwp/<lwpid> directory.
 175  177   */
 176  178  static prdirent_t lwpiddir[] = {
↓ open down ↓ 230 lines elided ↑ open up ↑
 407  409          prunlock(pnp);
 408  410  
 409  411          if (npnp != NULL)
 410  412                  prfreenode(npnp);
 411  413          return (error);
 412  414  }
 413  415  
 414  416  /* ARGSUSED */
 415  417  static int
 416  418  prclose(vnode_t *vp, int flag, int count, offset_t offset, cred_t *cr,
 417      -        caller_context_t *ct)
      419 +    caller_context_t *ct)
 418  420  {
 419  421          prnode_t *pnp = VTOP(vp);
 420  422          prcommon_t *pcp = pnp->pr_pcommon;
 421  423          prnodetype_t type = pnp->pr_type;
 422  424          proc_t *p;
 423  425          kthread_t *t;
 424  426          user_t *up;
 425  427  
 426  428          /*
 427  429           * Nothing to do for the /proc directory itself.
↓ open down ↓ 150 lines elided ↑ open up ↑
 578  580  static int pr_read_inval(), pr_read_as(), pr_read_status(),
 579  581          pr_read_lstatus(), pr_read_psinfo(), pr_read_lpsinfo(),
 580  582          pr_read_map(), pr_read_rmap(), pr_read_xmap(),
 581  583          pr_read_cred(), pr_read_sigact(), pr_read_auxv(),
 582  584  #if defined(__x86)
 583  585          pr_read_ldt(),
 584  586  #endif
 585  587          pr_read_usage(), pr_read_lusage(), pr_read_pagedata(),
 586  588          pr_read_watch(), pr_read_lwpstatus(), pr_read_lwpsinfo(),
 587  589          pr_read_lwpusage(), pr_read_xregs(), pr_read_priv(),
 588      -        pr_read_spymaster(),
      590 +        pr_read_spymaster(), pr_read_secflags(),
 589  591  #if defined(__sparc)
 590  592          pr_read_gwindows(), pr_read_asrs(),
 591  593  #endif
 592  594          pr_read_piddir(), pr_read_pidfile(), pr_read_opagedata();
 593  595  
 594  596  static int (*pr_read_function[PR_NFILES])() = {
 595  597          pr_read_inval,          /* /proc                                */
 596  598          pr_read_inval,          /* /proc/self                           */
 597  599          pr_read_piddir,         /* /proc/<pid> (old /proc read())       */
 598  600          pr_read_as,             /* /proc/<pid>/as                       */
↓ open down ↓ 33 lines elided ↑ open up ↑
 632  634          pr_read_spymaster,      /* /proc/<pid>/lwp/<lwpid>/spymaster    */
 633  635  #if defined(__sparc)
 634  636          pr_read_gwindows,       /* /proc/<pid>/lwp/<lwpid>/gwindows     */
 635  637          pr_read_asrs,           /* /proc/<pid>/lwp/<lwpid>/asrs         */
 636  638  #endif
 637  639          pr_read_priv,           /* /proc/<pid>/priv                     */
 638  640          pr_read_inval,          /* /proc/<pid>/path                     */
 639  641          pr_read_inval,          /* /proc/<pid>/path/xxx                 */
 640  642          pr_read_inval,          /* /proc/<pid>/contracts                */
 641  643          pr_read_inval,          /* /proc/<pid>/contracts/<ctid>         */
      644 +        pr_read_secflags,       /* /proc/<pid>/secflags                 */
 642  645          pr_read_pidfile,        /* old process file                     */
 643  646          pr_read_pidfile,        /* old lwp file                         */
 644  647          pr_read_opagedata,      /* old pagedata file                    */
 645  648  };
 646  649  
 647  650  /* ARGSUSED */
 648  651  static int
 649  652  pr_read_inval(prnode_t *pnp, uio_t *uiop)
 650  653  {
 651  654          /*
↓ open down ↓ 942 lines elided ↑ open up ↑
1594 1597                  prunlock(pnp);
1595 1598                  return (0);
1596 1599          }
1597 1600  
1598 1601          bcopy(lwp->lwp_spymaster, &psinfo, sizeof (psinfo_t));
1599 1602          prunlock(pnp);
1600 1603  
1601 1604          return (pr_uioread(&psinfo, sizeof (psinfo), uiop));
1602 1605  }
1603 1606  
     1607 +static int
     1608 +pr_read_secflags(prnode_t *pnp, uio_t *uiop)
     1609 +{
     1610 +        prsecflags_t ret;
     1611 +        int error;
     1612 +        proc_t *p;
     1613 +
     1614 +        ASSERT(pnp->pr_type == PR_SECFLAGS);
     1615 +
     1616 +        if ((error = prlock(pnp, ZNO)) != 0)
     1617 +                return (error);
     1618 +
     1619 +        p = pnp->pr_common->prc_proc;
     1620 +        prgetsecflags(p, &ret);
     1621 +        prunlock(pnp);
     1622 +
     1623 +        return (pr_uioread(&ret, sizeof (ret), uiop));
     1624 +}
     1625 +
1604 1626  #if defined(__sparc)
1605 1627  
1606 1628  static int
1607 1629  pr_read_gwindows(prnode_t *pnp, uio_t *uiop)
1608 1630  {
1609 1631          proc_t *p;
1610 1632          kthread_t *t;
1611 1633          gwindows_t *gwp;
1612 1634          int error;
1613 1635          size_t size;
↓ open down ↓ 175 lines elided ↑ open up ↑
1789 1811          pr_read_spymaster_32,   /* /proc/<pid>/lwp/<lwpid>/spymaster    */
1790 1812  #if defined(__sparc)
1791 1813          pr_read_gwindows_32,    /* /proc/<pid>/lwp/<lwpid>/gwindows     */
1792 1814          pr_read_asrs,           /* /proc/<pid>/lwp/<lwpid>/asrs         */
1793 1815  #endif
1794 1816          pr_read_priv,           /* /proc/<pid>/priv                     */
1795 1817          pr_read_inval,          /* /proc/<pid>/path                     */
1796 1818          pr_read_inval,          /* /proc/<pid>/path/xxx                 */
1797 1819          pr_read_inval,          /* /proc/<pid>/contracts                */
1798 1820          pr_read_inval,          /* /proc/<pid>/contracts/<ctid>         */
     1821 +        pr_read_secflags,       /* /proc/<pid>/secflags                 */
1799 1822          pr_read_pidfile,        /* old process file                     */
1800 1823          pr_read_pidfile,        /* old lwp file                         */
1801 1824          pr_read_opagedata_32,   /* old pagedata file                    */
1802 1825  };
1803 1826  
1804 1827  static int
1805 1828  pr_read_status_32(prnode_t *pnp, uio_t *uiop)
1806 1829  {
1807 1830          pstatus32_t *sp;
1808 1831          proc_t *p;
↓ open down ↓ 956 lines elided ↑ open up ↑
2765 2788                  return (error);
2766 2789  
2767 2790          default:
2768 2791                  return ((vp->v_type == VDIR)? EISDIR : EBADF);
2769 2792          }
2770 2793          /* NOTREACHED */
2771 2794  }
2772 2795  
2773 2796  static int
2774 2797  prgetattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr,
2775      -        caller_context_t *ct)
     2798 +    caller_context_t *ct)
2776 2799  {
2777 2800          prnode_t *pnp = VTOP(vp);
2778 2801          prnodetype_t type = pnp->pr_type;
2779 2802          prcommon_t *pcp;
2780 2803          proc_t *p;
2781 2804          struct as *as;
2782 2805          int error;
2783 2806          vnode_t *rvp;
2784 2807          timestruc_t now;
2785 2808          extern uint_t nproc;
↓ open down ↓ 246 lines elided ↑ open up ↑
3032 3055                  mutex_enter(&p->p_crlock);
3033 3056                  vap->va_size = sizeof (prcred_t);
3034 3057                  ngroups = crgetngroups(p->p_cred);
3035 3058                  if (ngroups > 1)
3036 3059                          vap->va_size += (ngroups - 1) * sizeof (gid_t);
3037 3060                  mutex_exit(&p->p_crlock);
3038 3061                  break;
3039 3062          case PR_PRIV:
3040 3063                  vap->va_size = prgetprivsize();
3041 3064                  break;
     3065 +        case PR_SECFLAGS:
     3066 +                vap->va_size = sizeof (prsecflags_t);
     3067 +                break;
3042 3068          case PR_SIGACT:
3043 3069                  nsig = PROC_IS_BRANDED(curproc)? BROP(curproc)->b_nsig : NSIG;
3044 3070                  vap->va_size = (nsig-1) *
3045 3071                      PR_OBJSIZE(struct sigaction32, struct sigaction);
3046 3072                  break;
3047 3073          case PR_AUXV:
3048 3074                  vap->va_size = __KERN_NAUXV_IMPL * PR_OBJSIZE(auxv32_t, auxv_t);
3049 3075                  break;
3050 3076  #if defined(__x86)
3051 3077          case PR_LDT:
↓ open down ↓ 277 lines elided ↑ open up ↑
3329 3355          pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/spymaster    */
3330 3356  #if defined(__sparc)
3331 3357          pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/gwindows     */
3332 3358          pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/asrs         */
3333 3359  #endif
3334 3360          pr_lookup_notdir,       /* /proc/<pid>/priv                     */
3335 3361          pr_lookup_pathdir,      /* /proc/<pid>/path                     */
3336 3362          pr_lookup_notdir,       /* /proc/<pid>/path/xxx                 */
3337 3363          pr_lookup_ctdir,        /* /proc/<pid>/contracts                */
3338 3364          pr_lookup_notdir,       /* /proc/<pid>/contracts/<ctid>         */
     3365 +        pr_lookup_notdir,       /* /proc/<pid>/secflags                 */
3339 3366          pr_lookup_notdir,       /* old process file                     */
3340 3367          pr_lookup_notdir,       /* old lwp file                         */
3341 3368          pr_lookup_notdir,       /* old pagedata file                    */
3342 3369  };
3343 3370  
3344 3371  static int
3345 3372  prlookup(vnode_t *dp, char *comp, vnode_t **vpp, pathname_t *pathp,
3346      -        int flags, vnode_t *rdir, cred_t *cr, caller_context_t *ct,
3347      -        int *direntflags, pathname_t *realpnp)
     3373 +    int flags, vnode_t *rdir, cred_t *cr, caller_context_t *ct,
     3374 +    int *direntflags, pathname_t *realpnp)
3348 3375  {
3349 3376          prnode_t *pnp = VTOP(dp);
3350 3377          prnodetype_t type = pnp->pr_type;
3351 3378          int error;
3352 3379  
3353 3380          ASSERT(dp->v_type == VDIR);
3354 3381          ASSERT(type < PR_NFILES);
3355 3382  
3356 3383          if (type != PR_PROCDIR && strcmp(comp, "..") == 0) {
3357 3384                  VN_HOLD(pnp->pr_parent);
↓ open down ↓ 29 lines elided ↑ open up ↑
3387 3414  
3388 3415          /* XXX - Do we need to pass ct, direntflags, or realpnp? */
3389 3416          *vpp = (pr_lookup_function[type](dp, comp));
3390 3417  
3391 3418          return ((*vpp == NULL) ? ENOENT : 0);
3392 3419  }
3393 3420  
3394 3421  /* ARGSUSED */
3395 3422  static int
3396 3423  prcreate(vnode_t *dp, char *comp, vattr_t *vap, vcexcl_t excl,
3397      -        int mode, vnode_t **vpp, cred_t *cr, int flag, caller_context_t *ct,
3398      -        vsecattr_t *vsecp)
     3424 +    int mode, vnode_t **vpp, cred_t *cr, int flag, caller_context_t *ct,
     3425 +    vsecattr_t *vsecp)
3399 3426  {
3400 3427          int error;
3401 3428  
3402 3429          if ((error = prlookup(dp, comp, vpp, NULL, 0, NULL, cr,
3403 3430              ct, NULL, NULL)) != 0) {
3404 3431                  if (error == ENOENT)    /* can't O_CREAT nonexistent files */
3405 3432                          error = EACCES;         /* unwriteable directories */
3406 3433          } else {
3407 3434                  if (excl == EXCL)                       /* O_EXCL */
3408 3435                          error = EEXIST;
↓ open down ↓ 1269 lines elided ↑ open up ↑
4678 4705          pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/spymaster    */
4679 4706  #if defined(__sparc)
4680 4707          pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/gwindows     */
4681 4708          pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/asrs         */
4682 4709  #endif
4683 4710          pr_readdir_notdir,      /* /proc/<pid>/priv                     */
4684 4711          pr_readdir_pathdir,     /* /proc/<pid>/path                     */
4685 4712          pr_readdir_notdir,      /* /proc/<pid>/path/xxx                 */
4686 4713          pr_readdir_ctdir,       /* /proc/<pid>/contracts                */
4687 4714          pr_readdir_notdir,      /* /proc/<pid>/contracts/<ctid>         */
     4715 +        pr_readdir_notdir,      /* /proc/<pid>/secflags                 */
4688 4716          pr_readdir_notdir,      /* old process file                     */
4689 4717          pr_readdir_notdir,      /* old lwp file                         */
4690 4718          pr_readdir_notdir,      /* old pagedata file                    */
4691 4719  };
4692 4720  
4693 4721  /* ARGSUSED */
4694 4722  static int
4695 4723  prreaddir(vnode_t *vp, uio_t *uiop, cred_t *cr, int *eofp,
4696      -        caller_context_t *ct, int flags)
     4724 +    caller_context_t *ct, int flags)
4697 4725  {
4698 4726          prnode_t *pnp = VTOP(vp);
4699 4727  
4700 4728          ASSERT(pnp->pr_type < PR_NFILES);
4701 4729  
4702 4730          /* XXX - Do we need to pass ct and flags? */
4703 4731          return (pr_readdir_function[pnp->pr_type](pnp, uiop, eofp));
4704 4732  }
4705 4733  
4706 4734  /* ARGSUSED */
↓ open down ↓ 1195 lines elided ↑ open up ↑
5902 5930   * Return the answer requested to poll().
5903 5931   * POLLIN, POLLRDNORM, and POLLOUT are recognized as in fs_poll().
5904 5932   * In addition, these have special meaning for /proc files:
5905 5933   *      POLLPRI         process or lwp stopped on an event of interest
5906 5934   *      POLLERR         /proc file descriptor is invalid
5907 5935   *      POLLHUP         process or lwp has terminated
5908 5936   */
5909 5937  /*ARGSUSED5*/
5910 5938  static int
5911 5939  prpoll(vnode_t *vp, short events, int anyyet, short *reventsp,
5912      -        pollhead_t **phpp, caller_context_t *ct)
     5940 +    pollhead_t **phpp, caller_context_t *ct)
5913 5941  {
5914 5942          prnode_t *pnp = VTOP(vp);
5915 5943          prcommon_t *pcp = pnp->pr_common;
5916 5944          pollhead_t *php = &pcp->prc_pollhead;
5917 5945          proc_t *p;
5918 5946          short revents;
5919 5947          int error;
5920 5948          int lockstate;
5921 5949  
5922 5950          ASSERT(pnp->pr_type < PR_NFILES);
↓ open down ↓ 137 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX