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/lib/librestart/common/librestart.c
          +++ new/usr/src/lib/librestart/common/librestart.c
↓ open down ↓ 45 lines elided ↑ open up ↑
  46   46  #include <project.h>
  47   47  #include <pthread.h>
  48   48  #include <pwd.h>
  49   49  #include <secdb.h>
  50   50  #include <signal.h>
  51   51  #include <stdlib.h>
  52   52  #include <string.h>
  53   53  #include <syslog.h>
  54   54  #include <sys/corectl.h>
  55   55  #include <sys/machelf.h>
       56 +#include <sys/secflags.h>
  56   57  #include <sys/task.h>
  57   58  #include <sys/types.h>
  58   59  #include <time.h>
  59   60  #include <unistd.h>
  60   61  #include <ucontext.h>
  61   62  
  62   63  #define min(a, b)               ((a) > (b) ? (b) : (a))
  63   64  
  64   65  #define MKW_TRUE        ":true"
  65   66  #define MKW_KILL        ":kill"
↓ open down ↓ 2770 lines elided ↑ open up ↑
2836 2837          if (cip->vbuf == NULL) {
2837 2838                  free(cip);
2838 2839                  return (mc_error_create(err, ENOMEM, ALLOCFAIL));
2839 2840          }
2840 2841  
2841 2842          if ((instpg = scf_pg_create(h)) == NULL ||
2842 2843              (methpg = scf_pg_create(h)) == NULL ||
2843 2844              (prop = scf_property_create(h)) == NULL ||
2844 2845              (val = scf_value_create(h)) == NULL) {
2845 2846                  err = mc_error_create(err, scf_error(),
2846      -                    "Failed to create repository object: %s\n",
     2847 +                    "Failed to create repository object: %s",
2847 2848                      scf_strerror(scf_error()));
2848 2849                  goto out;
2849 2850          }
2850 2851  
2851 2852          /*
2852 2853           * The method environment, and the credentials/profile data,
2853 2854           * may be found either in the pg for the method (methpg),
2854 2855           * or in the instance/service SCF_PG_METHOD_CONTEXT pg (named
2855 2856           * instpg below).
2856 2857           */
↓ open down ↓ 31 lines elided ↑ open up ↑
2888 2889          case ENOENT:
2889 2890                  break;
2890 2891          case ENOMEM:
2891 2892                  err = mc_error_create(err, ret, "Out of memory.");
2892 2893                  goto out;
2893 2894          case EINVAL:
2894 2895                  err = mc_error_create(err, ret, "Invalid method environment.");
2895 2896                  goto out;
2896 2897          default:
2897 2898                  err = mc_error_create(err, ret,
2898      -                    "Get method environment failed : %s\n", scf_strerror(ret));
     2899 +                    "Get method environment failed: %s", scf_strerror(ret));
2899 2900                  goto out;
2900 2901          }
2901 2902  
2902 2903          pg = methpg;
2903 2904  
2904 2905          ret = scf_pg_get_property(pg, SCF_PROPERTY_USE_PROFILE, prop);
2905 2906          if (ret && scf_error() == SCF_ERROR_NOT_FOUND && instpg != NULL) {
2906 2907                  pg = NULL;
2907 2908                  ret = scf_pg_get_property(instpg, SCF_PROPERTY_USE_PROFILE,
2908 2909                      prop);
↓ open down ↓ 187 lines elided ↑ open up ↑
3096 3097                          goto out;
3097 3098                  }
3098 3099          } else {
3099 3100                  cip->working_dir = strdup(cip->vbuf);
3100 3101                  if (cip->working_dir == NULL) {
3101 3102                          err = mc_error_create(err, ENOMEM, ALLOCFAIL);
3102 3103                          goto out;
3103 3104                  }
3104 3105          }
3105 3106  
     3107 +        /* get security flags */
     3108 +        if ((methpg != NULL && scf_pg_get_property(methpg,
     3109 +            SCF_PROPERTY_SECFLAGS, prop) == SCF_SUCCESS) ||
     3110 +            (instpg != NULL && scf_pg_get_property(instpg,
     3111 +            SCF_PROPERTY_SECFLAGS, prop) == SCF_SUCCESS)) {
     3112 +                if (scf_property_get_value(prop, val) != SCF_SUCCESS) {
     3113 +                        ret = scf_error();
     3114 +                        switch (ret) {
     3115 +                        case SCF_ERROR_CONNECTION_BROKEN:
     3116 +                                err = mc_error_create(err, ret, RCBROKEN);
     3117 +                                break;
     3118 +
     3119 +                        case SCF_ERROR_CONSTRAINT_VIOLATED:
     3120 +                                err = mc_error_create(err, ret,
     3121 +                                    "\"%s\" property has multiple values.",
     3122 +                                    SCF_PROPERTY_SECFLAGS);
     3123 +                                break;
     3124 +
     3125 +                        case SCF_ERROR_NOT_FOUND:
     3126 +                                err = mc_error_create(err, ret,
     3127 +                                    "\"%s\" property has no values.",
     3128 +                                    SCF_PROPERTY_SECFLAGS);
     3129 +                                break;
     3130 +
     3131 +                        default:
     3132 +                                bad_fail("scf_property_get_value", ret);
     3133 +                        }
     3134 +
     3135 +                        (void) strlcpy(cip->vbuf, ":default", cip->vbuf_sz);
     3136 +                } else {
     3137 +                        ret = scf_value_get_astring(val, cip->vbuf,
     3138 +                            cip->vbuf_sz);
     3139 +                        assert(ret != -1);
     3140 +                }
     3141 +                mc_used++;
     3142 +        } else {
     3143 +                ret = scf_error();
     3144 +                switch (ret) {
     3145 +                case SCF_ERROR_NOT_FOUND:
     3146 +                        /* okay if missing. */
     3147 +                        (void) strlcpy(cip->vbuf, ":default", cip->vbuf_sz);
     3148 +                        break;
     3149 +
     3150 +                case SCF_ERROR_CONNECTION_BROKEN:
     3151 +                        err = mc_error_create(err, ret, RCBROKEN);
     3152 +                        goto out;
     3153 +
     3154 +                case SCF_ERROR_DELETED:
     3155 +                        err = mc_error_create(err, ret,
     3156 +                            "Property group could not be found");
     3157 +                        goto out;
     3158 +
     3159 +                case SCF_ERROR_HANDLE_MISMATCH:
     3160 +                case SCF_ERROR_INVALID_ARGUMENT:
     3161 +                case SCF_ERROR_NOT_SET:
     3162 +                default:
     3163 +                        bad_fail("scf_pg_get_property", ret);
     3164 +                }
     3165 +        }
     3166 +
     3167 +
     3168 +        if (scf_default_secflags(h, &cip->def_secflags) != 0) {
     3169 +                err = mc_error_create(err, EINVAL, "couldn't fetch "
     3170 +                    "default security-flags");
     3171 +                goto out;
     3172 +        }
     3173 +
     3174 +        if (strcmp(cip->vbuf, ":default") == 0) {
     3175 +                if (secflags_parse(&cip->def_secflags.psf_inherit, "default",
     3176 +                    &cip->secflag_delta) != 0) {
     3177 +                        err = mc_error_create(err, EINVAL, "couldn't parse "
     3178 +                            "security flags: %s", cip->vbuf);
     3179 +                        goto out;
     3180 +                }
     3181 +        } else {
     3182 +                if (secflags_parse(&cip->def_secflags.psf_inherit, cip->vbuf,
     3183 +                    &cip->secflag_delta) != 0) {
     3184 +                        err = mc_error_create(err, EINVAL, "couldn't parse "
     3185 +                            "security flags: %s", cip->vbuf);
     3186 +                        goto out;
     3187 +                }
     3188 +        }
     3189 +
3106 3190          /* get (optional) corefile pattern */
3107 3191          if ((methpg != NULL && scf_pg_get_property(methpg,
3108 3192              SCF_PROPERTY_COREFILE_PATTERN, prop) == SCF_SUCCESS) ||
3109 3193              (instpg != NULL && scf_pg_get_property(instpg,
3110 3194              SCF_PROPERTY_COREFILE_PATTERN, prop) == SCF_SUCCESS)) {
3111 3195                  if (scf_property_get_value(prop, val) != SCF_SUCCESS) {
3112 3196                          ret = scf_error();
3113 3197                          switch (ret) {
3114 3198                          case SCF_ERROR_CONNECTION_BROKEN:
3115 3199                                  err = mc_error_create(err, ret, RCBROKEN);
↓ open down ↓ 220 lines elided ↑ open up ↑
3336 3420          if (mc_used == 0) {
3337 3421                  free(cip->pwbuf);
3338 3422                  free(cip->vbuf);
3339 3423                  free(cip->working_dir);
3340 3424  
3341 3425                  (void) memset(cip, 0, sizeof (*cip));
3342 3426                  cip->uid = 0;
3343 3427                  cip->gid = 0;
3344 3428                  cip->euid = (uid_t)-1;
3345 3429                  cip->egid = (gid_t)-1;
     3430 +
     3431 +                if (scf_default_secflags(h, &cip->def_secflags) != 0) {
     3432 +                        err = mc_error_create(err, EINVAL, "couldn't fetch "
     3433 +                            "default security-flags");
     3434 +                        goto out;
     3435 +                }
     3436 +
     3437 +                if (secflags_parse(&cip->def_secflags.psf_inherit, "default",
     3438 +                    &cip->secflag_delta) != 0) {
     3439 +                        err = mc_error_create(err, EINVAL, "couldn't parse "
     3440 +                            "security flags: %s", cip->vbuf);
     3441 +                        goto out;
     3442 +                }
3346 3443          }
3347 3444  
3348 3445          *mcpp = cip;
3349 3446  
3350 3447  out:
3351 3448          (void) scf_value_destroy(val);
3352 3449          scf_property_destroy(prop);
3353 3450          scf_pg_destroy(instpg);
3354 3451          scf_pg_destroy(methpg);
3355 3452  
↓ open down ↓ 52 lines elided ↑ open up ↑
3408 3505   *   EBADF - the configuration for the pool is invalid (pool_set_binding)
3409 3506   *   -1 - core_set_process_path() failed (core_set_process_path)
3410 3507   *        a resource control assignment failed (setproject)
3411 3508   *        a system error occurred during pool_set_binding (pool_set_binding)
3412 3509   */
3413 3510  int
3414 3511  restarter_set_method_context(struct method_context *cip, const char **fp)
3415 3512  {
3416 3513          pid_t mypid = -1;
3417 3514          int r, ret;
     3515 +        secflagdelta_t delta = {0};
3418 3516  
3419 3517          cip->pwbuf = NULL;
3420 3518          *fp = NULL;
3421 3519  
3422 3520          if (cip->gid != (gid_t)-1) {
3423 3521                  if (setregid(cip->gid,
3424 3522                      cip->egid != (gid_t)-1 ? cip->egid : cip->gid) != 0) {
3425 3523                          *fp = "setregid";
3426 3524  
3427 3525                          ret = errno;
↓ open down ↓ 75 lines elided ↑ open up ↑
3503 3601                  mypid = getpid();
3504 3602  
3505 3603                  if (core_set_process_path(cip->corefile_pattern,
3506 3604                      strlen(cip->corefile_pattern) + 1, mypid) != 0) {
3507 3605                          *fp = "core_set_process_path";
3508 3606                          ret = -1;
3509 3607                          goto out;
3510 3608                  }
3511 3609          }
3512 3610  
     3611 +
     3612 +        delta.psd_ass_active = B_TRUE;
     3613 +        secflags_copy(&delta.psd_assign, &cip->def_secflags.psf_inherit);
     3614 +        if (psecflags(P_PID, P_MYID, PSF_INHERIT,
     3615 +            &delta) != 0) {
     3616 +                *fp = "psecflags (inherit defaults)";
     3617 +                ret = errno;
     3618 +                goto out;
     3619 +        }
     3620 +
     3621 +        if (psecflags(P_PID, P_MYID, PSF_INHERIT,
     3622 +            &cip->secflag_delta) != 0) {
     3623 +                *fp = "psecflags (inherit)";
     3624 +                ret = errno;
     3625 +                goto out;
     3626 +        }
     3627 +
     3628 +        secflags_copy(&delta.psd_assign, &cip->def_secflags.psf_lower);
     3629 +        if (psecflags(P_PID, P_MYID, PSF_LOWER,
     3630 +            &delta) != 0) {
     3631 +                *fp = "psecflags (lower)";
     3632 +                ret = errno;
     3633 +                goto out;
     3634 +        }
     3635 +
     3636 +        secflags_copy(&delta.psd_assign, &cip->def_secflags.psf_upper);
     3637 +        if (psecflags(P_PID, P_MYID, PSF_UPPER,
     3638 +            &delta) != 0) {
     3639 +                *fp = "psecflags (upper)";
     3640 +                ret = errno;
     3641 +                goto out;
     3642 +        }
     3643 +
3513 3644          if (restarter_rm_libs_loadable()) {
3514 3645                  if (cip->project == NULL) {
3515 3646                          if (settaskid(getprojid(), TASK_NORMAL) == -1) {
3516 3647                                  switch (errno) {
3517 3648                                  case EACCES:
3518 3649                                  case EPERM:
3519 3650                                          *fp = "settaskid";
3520 3651                                          ret = errno;
3521 3652                                          goto out;
3522 3653  
↓ open down ↓ 502 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX