diff options
Diffstat (limited to 'usr/src/uts/common/os/zone.c')
-rw-r--r-- | usr/src/uts/common/os/zone.c | 54 |
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(); |