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/os/policy.c
          +++ new/usr/src/uts/common/os/policy.c
↓ open down ↓ 137 lines elided ↑ open up ↑
 138  138   * The privileges are checked against the Effective set for
 139  139   * ordinary processes and checked against the Limit set
 140  140   * for euid 0 processes that haven't manipulated their privilege
 141  141   * sets.
 142  142   */
 143  143  #define HAS_ALLPRIVS(cr)        priv_isfullset(&CR_OEPRIV(cr))
 144  144  #define ZONEPRIVS(cr)           ((cr)->cr_zone->zone_privset)
 145  145  #define HAS_ALLZONEPRIVS(cr)    priv_issubset(ZONEPRIVS(cr), &CR_OEPRIV(cr))
 146  146  #define HAS_PRIVILEGE(cr, pr)   ((pr) == PRIV_ALL ? \
 147  147                                          HAS_ALLPRIVS(cr) : \
 148      -                                        PRIV_ISASSERT(&CR_OEPRIV(cr), pr))
      148 +                                        PRIV_ISMEMBER(&CR_OEPRIV(cr), pr))
 149  149  
 150  150  #define FAST_BASIC_CHECK(cr, priv)      \
 151      -        if (PRIV_ISASSERT(&CR_OEPRIV(cr), priv)) { \
      151 +        if (PRIV_ISMEMBER(&CR_OEPRIV(cr), priv)) { \
 152  152                  DTRACE_PROBE2(priv__ok, int, priv, boolean_t, B_FALSE); \
 153  153                  return (0); \
 154  154          }
 155  155  
 156  156  /*
 157  157   * Policy checking functions.
 158  158   *
 159  159   * All of the system's policy should be implemented here.
 160  160   */
 161  161  
↓ open down ↓ 232 lines elided ↑ open up ↑
 394  394   * See block comment above for a description of "priv" and "allzone" usage.
 395  395   */
 396  396  static int
 397  397  priv_policy_ap(const cred_t *cr, int priv, boolean_t allzone, int err,
 398  398      const char *msg, va_list ap)
 399  399  {
 400  400          if ((HAS_PRIVILEGE(cr, priv) && (!allzone || HAS_ALLZONEPRIVS(cr))) ||
 401  401              (!servicing_interrupt() &&
 402  402              priv_policy_override(cr, priv, allzone, ap) == 0)) {
 403  403                  if ((allzone || priv == PRIV_ALL ||
 404      -                    !PRIV_ISASSERT(priv_basic, priv)) &&
      404 +                    !PRIV_ISMEMBER(priv_basic, priv)) &&
 405  405                      !servicing_interrupt()) {
 406  406                          PTOU(curproc)->u_acflag |= ASU; /* Needed for SVVS */
 407  407                          if (AU_AUDITING())
 408  408                                  audit_priv(priv,
 409  409                                      allzone ? ZONEPRIVS(cr) : NULL, 1);
 410  410                  }
 411  411                  err = 0;
 412  412                  DTRACE_PROBE2(priv__ok, int, priv, boolean_t, allzone);
 413  413          } else if (!servicing_interrupt()) {
 414  414                  /* Failure audited in this procedure */
↓ open down ↓ 27 lines elided ↑ open up ↑
 442  442   * Return B_TRUE for sufficient privileges, B_FALSE for insufficient privileges.
 443  443   */
 444  444  boolean_t
 445  445  priv_policy_choice(const cred_t *cr, int priv, boolean_t allzone)
 446  446  {
 447  447          boolean_t res = HAS_PRIVILEGE(cr, priv) &&
 448  448              (!allzone || HAS_ALLZONEPRIVS(cr));
 449  449  
 450  450          /* Audit success only */
 451  451          if (res && AU_AUDITING() &&
 452      -            (allzone || priv == PRIV_ALL || !PRIV_ISASSERT(priv_basic, priv)) &&
      452 +            (allzone || priv == PRIV_ALL || !PRIV_ISMEMBER(priv_basic, priv)) &&
 453  453              !servicing_interrupt()) {
 454  454                  audit_priv(priv, allzone ? ZONEPRIVS(cr) : NULL, 1);
 455  455          }
 456  456          if (res) {
 457  457                  DTRACE_PROBE2(priv__ok, int, priv, boolean_t, allzone);
 458  458          } else {
 459  459                  DTRACE_PROBE2(priv__err, int, priv, boolean_t, allzone);
 460  460          }
 461  461          return (res);
 462  462  }
↓ open down ↓ 502 lines elided ↑ open up ↑
 965  965   * current mode of the file, not the missing bits.
 966  966   */
 967  967  int
 968  968  secpolicy_vnode_access2(const cred_t *cr, vnode_t *vp, uid_t owner,
 969  969      mode_t curmode, mode_t wantmode)
 970  970  {
 971  971          mode_t mode;
 972  972  
 973  973          /* Inline the basic privileges tests. */
 974  974          if ((wantmode & VREAD) &&
 975      -            !PRIV_ISASSERT(&CR_OEPRIV(cr), PRIV_FILE_READ) &&
      975 +            !PRIV_ISMEMBER(&CR_OEPRIV(cr), PRIV_FILE_READ) &&
 976  976              priv_policy_va(cr, PRIV_FILE_READ, B_FALSE, EACCES, NULL,
 977  977              KLPDARG_VNODE, vp, (char *)NULL, KLPDARG_NOMORE) != 0) {
 978  978                  return (EACCES);
 979  979          }
 980  980  
 981  981          if ((wantmode & VWRITE) &&
 982      -            !PRIV_ISASSERT(&CR_OEPRIV(cr), PRIV_FILE_WRITE) &&
      982 +            !PRIV_ISMEMBER(&CR_OEPRIV(cr), PRIV_FILE_WRITE) &&
 983  983              priv_policy_va(cr, PRIV_FILE_WRITE, B_FALSE, EACCES, NULL,
 984  984              KLPDARG_VNODE, vp, (char *)NULL, KLPDARG_NOMORE) != 0) {
 985  985                  return (EACCES);
 986  986          }
 987  987  
 988  988          mode = ~curmode & wantmode;
 989  989  
 990  990          if (mode == 0)
 991  991                  return (0);
 992  992  
↓ open down ↓ 384 lines elided ↑ open up ↑
1377 1377   * The ovap argument should include AT_MODE|AT_UID|AT_GID.
1378 1378   *
1379 1379   * If the vap argument does not include AT_MODE, the mode will be copied from
1380 1380   * ovap.  In certain situations set-uid/set-gid bits need to be removed;
1381 1381   * this is done by marking vap->va_mask to include AT_MODE and va_mode
1382 1382   * is updated to the newly computed mode.
1383 1383   */
1384 1384  
1385 1385  int
1386 1386  secpolicy_vnode_setattr(cred_t *cr, struct vnode *vp, struct vattr *vap,
1387      -        const struct vattr *ovap, int flags,
1388      -        int unlocked_access(void *, int, cred_t *),
1389      -        void *node)
     1387 +    const struct vattr *ovap, int flags,
     1388 +    int unlocked_access(void *, int, cred_t *),
     1389 +    void *node)
1390 1390  {
1391 1391          int mask = vap->va_mask;
1392 1392          int error = 0;
1393 1393          boolean_t skipaclchk = (flags & ATTR_NOACLCHECK) ? B_TRUE : B_FALSE;
1394 1394  
1395 1395          if (mask & AT_SIZE) {
1396 1396                  if (vp->v_type == VDIR) {
1397 1397                          error = EISDIR;
1398 1398                          goto out;
1399 1399                  }
↓ open down ↓ 321 lines elided ↑ open up ↑
1721 1721  
1722 1722  /*
1723 1723   * Processor sets, cpu configuration, resource pools.
1724 1724   */
1725 1725  int
1726 1726  secpolicy_pset(const cred_t *cr)
1727 1727  {
1728 1728          return (PRIV_POLICY(cr, PRIV_SYS_RES_CONFIG, B_FALSE, EPERM, NULL));
1729 1729  }
1730 1730  
     1731 +/* Process security flags */
     1732 +int
     1733 +secpolicy_psecflags(const cred_t *cr, proc_t *tp, proc_t *sp)
     1734 +{
     1735 +        if (PRIV_POLICY(cr, PRIV_PROC_SECFLAGS, B_FALSE, EPERM, NULL) != 0)
     1736 +                return (EPERM);
     1737 +
     1738 +        if (!prochasprocperm(tp, sp, cr))
     1739 +                return (EPERM);
     1740 +
     1741 +        return (0);
     1742 +}
     1743 +
1731 1744  /*
1732 1745   * Processor set binding.
1733 1746   */
1734 1747  int
1735 1748  secpolicy_pbind(const cred_t *cr)
1736 1749  {
1737 1750          if (PRIV_POLICY_ONLY(cr, PRIV_SYS_RES_CONFIG, B_FALSE))
1738 1751                  return (secpolicy_pset(cr));
1739 1752          return (PRIV_POLICY(cr, PRIV_SYS_RES_BIND, B_FALSE, EPERM, NULL));
1740 1753  }
↓ open down ↓ 843 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX