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: