summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/os/zone.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts/common/os/zone.c')
-rw-r--r--usr/src/uts/common/os/zone.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/usr/src/uts/common/os/zone.c b/usr/src/uts/common/os/zone.c
index 6b2625495f..81824f3196 100644
--- a/usr/src/uts/common/os/zone.c
+++ b/usr/src/uts/common/os/zone.c
@@ -2439,6 +2439,7 @@ zone_zsd_init(void)
zone0.zone_domain = srpc_domain;
zone0.zone_hostid = HW_INVALID_HOSTID;
zone0.zone_fs_allowed = NULL;
+ psecflags_default(&zone0.zone_secflags);
zone0.zone_ref = 1;
zone0.zone_id = GLOBAL_ZONEID;
zone0.zone_status = ZONE_IS_RUNNING;
@@ -2949,6 +2950,32 @@ zone_set_brand(zone_t *zone, const char *brand)
}
static int
+zone_set_secflags(zone_t *zone, const psecflags_t *zone_secflags)
+{
+ int err = 0;
+ psecflags_t psf;
+
+ ASSERT(zone != global_zone);
+
+ if ((err = copyin(zone_secflags, &psf, sizeof (psf))) != 0)
+ return (err);
+
+ if (zone_status_get(zone) > ZONE_IS_READY)
+ return (EINVAL);
+
+ if (!psecflags_validate(&psf))
+ return (EINVAL);
+
+ (void) memcpy(&zone->zone_secflags, &psf, sizeof (psf));
+
+ /* Set security flags on the zone's zsched */
+ (void) memcpy(&zone->zone_zsched->p_secflags, &zone->zone_secflags,
+ sizeof (zone->zone_zsched->p_secflags));
+
+ return (0);
+}
+
+static int
zone_set_fs_allowed(zone_t *zone, const char *zone_fs_allowed)
{
char *buf = kmem_zalloc(ZONE_FS_ALLOWED_MAX, KM_SLEEP);
@@ -4524,6 +4551,7 @@ zsched(void *arg)
mutex_exit(&pp->p_lock);
}
}
+
/*
* Tell the world that we're done setting up.
*
@@ -5081,6 +5109,12 @@ zone_create(const char *zone_name, const char *zone_root,
zone->zone_ipc.ipcq_msgmni = 0;
zone->zone_bootargs = NULL;
zone->zone_fs_allowed = NULL;
+
+ secflags_zero(&zone0.zone_secflags.psf_lower);
+ secflags_zero(&zone0.zone_secflags.psf_effective);
+ secflags_zero(&zone0.zone_secflags.psf_inherit);
+ secflags_fullset(&zone0.zone_secflags.psf_upper);
+
zone->zone_initname =
kmem_alloc(strlen(zone_default_initname) + 1, KM_SLEEP);
(void) strcpy(zone->zone_initname, zone_default_initname);
@@ -6208,6 +6242,13 @@ zone_getattr(zoneid_t zoneid, int attr, void *buf, size_t bufsize)
error = EFAULT;
}
break;
+ case ZONE_ATTR_SECFLAGS:
+ size = sizeof (zone->zone_secflags);
+ if (bufsize > size)
+ bufsize = size;
+ if ((err = copyout(&zone->zone_secflags, buf, bufsize)) != 0)
+ error = EFAULT;
+ break;
case ZONE_ATTR_NETWORK:
zbuf = kmem_alloc(bufsize, KM_SLEEP);
if (copyin(buf, zbuf, bufsize) != 0) {
@@ -6323,6 +6364,8 @@ zone_setattr(zoneid_t zoneid, int attr, void *buf, size_t bufsize)
break;
case ZONE_ATTR_RSS:
err = zone_set_rss(zone, (const uint64_t *)buf);
+ case ZONE_ATTR_SECFLAGS:
+ err = zone_set_secflags(zone, (psecflags_t *)buf);
break;
case ZONE_ATTR_SCHED_CLASS:
err = zone_set_sched_class(zone, (const char *)buf);
@@ -6824,6 +6867,17 @@ zone_enter(zoneid_t zoneid)
zone_chdir(vp, &PTOU(pp)->u_rdir, pp);
/*
+ * Change process security flags. Note that the _effective_ flags
+ * cannot change
+ */
+ secflags_copy(&pp->p_secflags.psf_lower,
+ &zone->zone_secflags.psf_lower);
+ secflags_copy(&pp->p_secflags.psf_upper,
+ &zone->zone_secflags.psf_upper);
+ secflags_copy(&pp->p_secflags.psf_inherit,
+ &zone->zone_secflags.psf_inherit);
+
+ /*
* Change process credentials
*/
newcr = cralloc();