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.

@@ -51,10 +51,11 @@
 #include <stdlib.h>
 #include <string.h>
 #include <syslog.h>
 #include <sys/corectl.h>
 #include <sys/machelf.h>
+#include <sys/secflags.h>
 #include <sys/task.h>
 #include <sys/types.h>
 #include <time.h>
 #include <unistd.h>
 #include <ucontext.h>

@@ -2841,11 +2842,11 @@
         if ((instpg = scf_pg_create(h)) == NULL ||
             (methpg = scf_pg_create(h)) == NULL ||
             (prop = scf_property_create(h)) == NULL ||
             (val = scf_value_create(h)) == NULL) {
                 err = mc_error_create(err, scf_error(),
-                    "Failed to create repository object: %s\n",
+                    "Failed to create repository object: %s",
                     scf_strerror(scf_error()));
                 goto out;
         }
 
         /*

@@ -2893,11 +2894,11 @@
         case EINVAL:
                 err = mc_error_create(err, ret, "Invalid method environment.");
                 goto out;
         default:
                 err = mc_error_create(err, ret,
-                    "Get method environment failed : %s\n", scf_strerror(ret));
+                    "Get method environment failed: %s", scf_strerror(ret));
                 goto out;
         }
 
         pg = methpg;
 

@@ -3101,10 +3102,93 @@
                         err = mc_error_create(err, ENOMEM, ALLOCFAIL);
                         goto out;
                 }
         }
 
+        /* get security flags */
+        if ((methpg != NULL && scf_pg_get_property(methpg,
+            SCF_PROPERTY_SECFLAGS, prop) == SCF_SUCCESS) ||
+            (instpg != NULL && scf_pg_get_property(instpg,
+            SCF_PROPERTY_SECFLAGS, prop) == SCF_SUCCESS)) {
+                if (scf_property_get_value(prop, val) != SCF_SUCCESS) {
+                        ret = scf_error();
+                        switch (ret) {
+                        case SCF_ERROR_CONNECTION_BROKEN:
+                                err = mc_error_create(err, ret, RCBROKEN);
+                                break;
+
+                        case SCF_ERROR_CONSTRAINT_VIOLATED:
+                                err = mc_error_create(err, ret,
+                                    "\"%s\" property has multiple values.",
+                                    SCF_PROPERTY_SECFLAGS);
+                                break;
+
+                        case SCF_ERROR_NOT_FOUND:
+                                err = mc_error_create(err, ret,
+                                    "\"%s\" property has no values.",
+                                    SCF_PROPERTY_SECFLAGS);
+                                break;
+
+                        default:
+                                bad_fail("scf_property_get_value", ret);
+                        }
+
+                        (void) strlcpy(cip->vbuf, ":default", cip->vbuf_sz);
+                } else {
+                        ret = scf_value_get_astring(val, cip->vbuf,
+                            cip->vbuf_sz);
+                        assert(ret != -1);
+                }
+                mc_used++;
+        } else {
+                ret = scf_error();
+                switch (ret) {
+                case SCF_ERROR_NOT_FOUND:
+                        /* okay if missing. */
+                        (void) strlcpy(cip->vbuf, ":default", cip->vbuf_sz);
+                        break;
+
+                case SCF_ERROR_CONNECTION_BROKEN:
+                        err = mc_error_create(err, ret, RCBROKEN);
+                        goto out;
+
+                case SCF_ERROR_DELETED:
+                        err = mc_error_create(err, ret,
+                            "Property group could not be found");
+                        goto out;
+
+                case SCF_ERROR_HANDLE_MISMATCH:
+                case SCF_ERROR_INVALID_ARGUMENT:
+                case SCF_ERROR_NOT_SET:
+                default:
+                        bad_fail("scf_pg_get_property", ret);
+                }
+        }
+
+
+        if (scf_default_secflags(h, &cip->def_secflags) != 0) {
+                err = mc_error_create(err, EINVAL, "couldn't fetch "
+                    "default security-flags");
+                goto out;
+        }
+
+        if (strcmp(cip->vbuf, ":default") == 0) {
+                if (secflags_parse(&cip->def_secflags.psf_inherit, "default",
+                    &cip->secflag_delta) != 0) {
+                        err = mc_error_create(err, EINVAL, "couldn't parse "
+                            "security flags: %s", cip->vbuf);
+                        goto out;
+                }
+        } else {
+                if (secflags_parse(&cip->def_secflags.psf_inherit, cip->vbuf,
+                    &cip->secflag_delta) != 0) {
+                        err = mc_error_create(err, EINVAL, "couldn't parse "
+                            "security flags: %s", cip->vbuf);
+                        goto out;
+                }
+        }
+
         /* get (optional) corefile pattern */
         if ((methpg != NULL && scf_pg_get_property(methpg,
             SCF_PROPERTY_COREFILE_PATTERN, prop) == SCF_SUCCESS) ||
             (instpg != NULL && scf_pg_get_property(instpg,
             SCF_PROPERTY_COREFILE_PATTERN, prop) == SCF_SUCCESS)) {

@@ -3341,10 +3425,23 @@
                 (void) memset(cip, 0, sizeof (*cip));
                 cip->uid = 0;
                 cip->gid = 0;
                 cip->euid = (uid_t)-1;
                 cip->egid = (gid_t)-1;
+
+                if (scf_default_secflags(h, &cip->def_secflags) != 0) {
+                        err = mc_error_create(err, EINVAL, "couldn't fetch "
+                            "default security-flags");
+                        goto out;
+                }
+
+                if (secflags_parse(&cip->def_secflags.psf_inherit, "default",
+                    &cip->secflag_delta) != 0) {
+                        err = mc_error_create(err, EINVAL, "couldn't parse "
+                            "security flags: %s", cip->vbuf);
+                        goto out;
+                }
         }
 
         *mcpp = cip;
 
 out:

@@ -3413,10 +3510,11 @@
 int
 restarter_set_method_context(struct method_context *cip, const char **fp)
 {
         pid_t mypid = -1;
         int r, ret;
+        secflagdelta_t delta = {0};
 
         cip->pwbuf = NULL;
         *fp = NULL;
 
         if (cip->gid != (gid_t)-1) {

@@ -3508,10 +3606,43 @@
                         ret = -1;
                         goto out;
                 }
         }
 
+
+        delta.psd_ass_active = B_TRUE;
+        secflags_copy(&delta.psd_assign, &cip->def_secflags.psf_inherit);
+        if (psecflags(P_PID, P_MYID, PSF_INHERIT,
+            &delta) != 0) {
+                *fp = "psecflags (inherit defaults)";
+                ret = errno;
+                goto out;
+        }
+
+        if (psecflags(P_PID, P_MYID, PSF_INHERIT,
+            &cip->secflag_delta) != 0) {
+                *fp = "psecflags (inherit)";
+                ret = errno;
+                goto out;
+        }
+
+        secflags_copy(&delta.psd_assign, &cip->def_secflags.psf_lower);
+        if (psecflags(P_PID, P_MYID, PSF_LOWER,
+            &delta) != 0) {
+                *fp = "psecflags (lower)";
+                ret = errno;
+                goto out;
+        }
+
+        secflags_copy(&delta.psd_assign, &cip->def_secflags.psf_upper);
+        if (psecflags(P_PID, P_MYID, PSF_UPPER,
+            &delta) != 0) {
+                *fp = "psecflags (upper)";
+                ret = errno;
+                goto out;
+        }
+
         if (restarter_rm_libs_loadable()) {
                 if (cip->project == NULL) {
                         if (settaskid(getprojid(), TASK_NORMAL) == -1) {
                                 switch (errno) {
                                 case EACCES: