From: Dan Walsh <dwalsh(a)redhat.com>
mcstransd is a translation tool that can translate MCS Labels into human
understandable code. I have patched it to watch for translation files in the
/run/setrans directory. This allows us to run commands like ps -eZ and see
system_u:system_r:svirt_t:Fedora18 rather then system_u:system_r:svirt_t:s0:c1,c2.
When used with containers it would make an easy way to list all processes within
a container using ps -eZ | grep Fedora18
Pass in privileged field into Security Manager so this is only attempted on privileged
machines
---
src/lxc/lxc_container.c | 8 +++---
src/lxc/lxc_controller.c | 2 +-
src/lxc/lxc_driver.c | 3 ++-
src/qemu/qemu_conf.c | 2 ++
src/qemu/qemu_conf.h | 1 +
src/qemu/qemu_driver.c | 9 ++++---
src/security/security_manager.c | 29 +++++++++++++++------
src/security/security_manager.h | 7 +++--
src/security/security_selinux.c | 57 ++++++++++++++++++++++++++++++++++++++++-
9 files changed, 98 insertions(+), 20 deletions(-)
diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
index 48ccc09..cb6ae6a 100644
--- a/src/lxc/lxc_container.c
+++ b/src/lxc/lxc_container.c
@@ -1829,6 +1829,10 @@ static int lxcContainerSetupPivotRoot(virDomainDefPtr vmDef,
if (lxcContainerPopulateDevices(ttyPaths, nttyPaths) < 0)
goto cleanup;
+ VIR_DEBUG("Setting up security labeling");
+ if (virSecurityManagerSetProcessLabel(securityDriver, vmDef) < 0)
+ goto cleanup;
+
/* Sets up any non-root mounts from guest config */
if (lxcContainerMountAllFS(vmDef, sec_mount_options) < 0)
goto cleanup;
@@ -2027,10 +2031,6 @@ static int lxcContainerChild(void *data)
goto cleanup;
}
- VIR_DEBUG("Setting up security labeling");
- if (virSecurityManagerSetProcessLabel(argv->securityDriver, vmDef) < 0)
- goto cleanup;
-
if (lxcContainerSetStdio(argv->monitor, ttyfd, argv->handshakefd) < 0) {
goto cleanup;
}
diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c
index 730236e..5a4c809 100644
--- a/src/lxc/lxc_controller.c
+++ b/src/lxc/lxc_controller.c
@@ -1732,7 +1732,7 @@ int main(int argc, char *argv[])
if (!(ctrl->securityManager = virSecurityManagerNew(securityDriver,
LXC_DRIVER_NAME,
- false, false, false)))
+ false, false, false, true)))
goto cleanup;
if (ctrl->def->seclabels) {
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index 997f81d..a80cc9b 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -1358,7 +1358,8 @@ lxcSecurityInit(virLXCDriverPtr driver)
LXC_DRIVER_NAME,
false,
driver->securityDefaultConfined,
-
driver->securityRequireConfined);
+ driver->securityRequireConfined,
+ true);
if (!mgr)
goto error;
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index 098e49c..b92a27b 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -250,6 +250,7 @@ virQEMUDriverConfigPtr virQEMUDriverConfigNew(bool privileged)
cfg->securityDefaultConfined = true;
cfg->securityRequireConfined = false;
+ cfg->securityPrivileged = privileged;
cfg->keepAliveInterval = 5;
cfg->keepAliveCount = 5;
@@ -399,6 +400,7 @@ int virQEMUDriverConfigLoadFile(virQEMUDriverConfigPtr cfg,
GET_VALUE_BOOL("security_default_confined",
cfg->securityDefaultConfined);
GET_VALUE_BOOL("security_require_confined",
cfg->securityRequireConfined);
+ GET_VALUE_BOOL("security_privileged", cfg->securityPrivileged);
GET_VALUE_BOOL("spice_tls", cfg->spiceTLS);
GET_VALUE_STR("spice_tls_x509_cert_dir", cfg->spiceTLSx509certdir);
diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
index df0791e..06824ae 100644
--- a/src/qemu/qemu_conf.h
+++ b/src/qemu/qemu_conf.h
@@ -138,6 +138,7 @@ struct _virQEMUDriverConfig {
char **securityDriverNames;
bool securityDefaultConfined;
bool securityRequireConfined;
+ bool securityPrivileged;
char *saveImageFormat;
char *dumpImageFormat;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 203cc6d..7a68e8a 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -322,7 +322,8 @@ qemuSecurityInit(virQEMUDriverPtr driver)
QEMU_DRIVER_NAME,
cfg->allowDiskFormatProbing,
cfg->securityDefaultConfined,
- cfg->securityRequireConfined)))
+ cfg->securityRequireConfined,
+ cfg->securityPrivileged)))
goto error;
if (!stack) {
if (!(stack = virSecurityManagerNewStack(mgr)))
@@ -339,7 +340,8 @@ qemuSecurityInit(virQEMUDriverPtr driver)
QEMU_DRIVER_NAME,
cfg->allowDiskFormatProbing,
cfg->securityDefaultConfined,
- cfg->securityRequireConfined)))
+ cfg->securityRequireConfined,
+ cfg->securityPrivileged)))
goto error;
if (!(stack = virSecurityManagerNewStack(mgr)))
goto error;
@@ -353,7 +355,8 @@ qemuSecurityInit(virQEMUDriverPtr driver)
cfg->allowDiskFormatProbing,
cfg->securityDefaultConfined,
cfg->securityRequireConfined,
- cfg->dynamicOwnership)))
+ cfg->dynamicOwnership,
+ cfg->securityPrivileged)))
goto error;
if (!stack) {
if (!(stack = virSecurityManagerNewStack(mgr)))
diff --git a/src/security/security_manager.c b/src/security/security_manager.c
index f7c5c2e..12b4d55 100644
--- a/src/security/security_manager.c
+++ b/src/security/security_manager.c
@@ -41,6 +41,7 @@ struct _virSecurityManager {
bool allowDiskFormatProbing;
bool defaultConfined;
bool requireConfined;
+ bool privileged;
const char *virtDriver;
void *privateData;
};
@@ -66,7 +67,8 @@ static virSecurityManagerPtr
virSecurityManagerNewDriver(virSecurityDriverPtr dr
const char *virtDriver,
bool allowDiskFormatProbing,
bool defaultConfined,
- bool requireConfined)
+ bool requireConfined,
+ bool privileged)
{
virSecurityManagerPtr mgr;
char *privateData;
@@ -75,10 +77,10 @@ static virSecurityManagerPtr
virSecurityManagerNewDriver(virSecurityDriverPtr dr
return NULL;
VIR_DEBUG("drv=%p (%s) virtDriver=%s allowDiskFormatProbing=%d "
- "defaultConfined=%d requireConfined=%d",
+ "defaultConfined=%d requireConfined=%d privileged=%d",
drv, drv->name, virtDriver,
allowDiskFormatProbing, defaultConfined,
- requireConfined);
+ requireConfined, privileged);
if (VIR_ALLOC_N(privateData, drv->privateDataLen) < 0) {
virReportOOMError();
@@ -94,6 +96,7 @@ static virSecurityManagerPtr
virSecurityManagerNewDriver(virSecurityDriverPtr dr
mgr->allowDiskFormatProbing = allowDiskFormatProbing;
mgr->defaultConfined = defaultConfined;
mgr->requireConfined = requireConfined;
+ mgr->privileged = privileged;
mgr->virtDriver = virtDriver;
mgr->privateData = privateData;
@@ -112,7 +115,8 @@ virSecurityManagerPtr virSecurityManagerNewStack(virSecurityManagerPtr
primary)
virSecurityManagerGetDriver(primary),
virSecurityManagerGetAllowDiskFormatProbing(primary),
virSecurityManagerGetDefaultConfined(primary),
- virSecurityManagerGetRequireConfined(primary));
+ virSecurityManagerGetRequireConfined(primary),
+ virSecurityManagerGetPrivileged(primary));
if (!mgr)
return NULL;
@@ -136,14 +140,16 @@ virSecurityManagerPtr virSecurityManagerNewDAC(const char
*virtDriver,
bool allowDiskFormatProbing,
bool defaultConfined,
bool requireConfined,
- bool dynamicOwnership)
+ bool dynamicOwnership,
+ bool privileged)
{
virSecurityManagerPtr mgr =
virSecurityManagerNewDriver(&virSecurityDriverDAC,
virtDriver,
allowDiskFormatProbing,
defaultConfined,
- requireConfined);
+ requireConfined,
+ privileged);
if (!mgr)
return NULL;
@@ -159,7 +165,8 @@ virSecurityManagerPtr virSecurityManagerNew(const char *name,
const char *virtDriver,
bool allowDiskFormatProbing,
bool defaultConfined,
- bool requireConfined)
+ bool requireConfined,
+ bool privileged)
{
virSecurityDriverPtr drv = virSecurityDriverLookup(name, virtDriver);
if (!drv)
@@ -189,7 +196,8 @@ virSecurityManagerPtr virSecurityManagerNew(const char *name,
virtDriver,
allowDiskFormatProbing,
defaultConfined,
- requireConfined);
+ requireConfined,
+ privileged);
}
@@ -278,6 +286,11 @@ bool virSecurityManagerGetRequireConfined(virSecurityManagerPtr mgr)
return mgr->requireConfined;
}
+bool virSecurityManagerGetPrivileged(virSecurityManagerPtr mgr)
+{
+ return mgr->privileged;
+}
+
int virSecurityManagerRestoreImageLabel(virSecurityManagerPtr mgr,
virDomainDefPtr vm,
virDomainDiskDefPtr disk)
diff --git a/src/security/security_manager.h b/src/security/security_manager.h
index 711b354..4d936a3 100644
--- a/src/security/security_manager.h
+++ b/src/security/security_manager.h
@@ -33,7 +33,8 @@ virSecurityManagerPtr virSecurityManagerNew(const char *name,
const char *virtDriver,
bool allowDiskFormatProbing,
bool defaultConfined,
- bool requireConfined);
+ bool requireConfined,
+ bool privileged);
virSecurityManagerPtr virSecurityManagerNewStack(virSecurityManagerPtr primary);
int virSecurityManagerStackAddNested(virSecurityManagerPtr stack,
@@ -45,7 +46,8 @@ virSecurityManagerPtr virSecurityManagerNewDAC(const char *virtDriver,
bool allowDiskFormatProbing,
bool defaultConfined,
bool requireConfined,
- bool dynamicOwnership);
+ bool dynamicOwnership,
+ bool privileged);
void virSecurityManagerPreFork(virSecurityManagerPtr mgr);
void virSecurityManagerPostFork(virSecurityManagerPtr mgr);
@@ -58,6 +60,7 @@ const char *virSecurityManagerGetModel(virSecurityManagerPtr mgr);
bool virSecurityManagerGetAllowDiskFormatProbing(virSecurityManagerPtr mgr);
bool virSecurityManagerGetDefaultConfined(virSecurityManagerPtr mgr);
bool virSecurityManagerGetRequireConfined(virSecurityManagerPtr mgr);
+bool virSecurityManagerGetPrivileged(virSecurityManagerPtr mgr);
int virSecurityManagerRestoreImageLabel(virSecurityManagerPtr mgr,
virDomainDefPtr def,
diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
index 5d108b9..c416666 100644
--- a/src/security/security_selinux.c
+++ b/src/security/security_selinux.c
@@ -83,6 +83,57 @@ virSecuritySELinuxRestoreSecurityTPMFileLabelInt(virSecurityManagerPtr
mgr,
virDomainTPMDefPtr tpm);
+static int
+virSecuritySELinuxAddMCSFile(const char *name,
+ const char *label)
+{
+ int ret = -1;
+ char *tmp = NULL;
+ context_t con = NULL;
+
+ if (virAsprintf(&tmp, "%s/%s", SELINUX_TRANS_DIR, name) < 0) {
+ virReportOOMError();
+ return -1;
+ }
+ if (!(con = context_new(label))) {
+ virReportSystemError(errno, "%s",
+ _("unable to allocate security context"));
+ goto cleanup;
+ }
+ if (virFileWriteStr(tmp, context_range_get(con), S_IRUSR|S_IWUSR) < 0) {
+ virReportSystemError(errno,
+ _("unable to create MCS file %s"), tmp);
+ goto cleanup;
+ }
+ ret = 0;
+
+cleanup:
+ VIR_FREE(tmp);
+ context_free(con);
+ return ret;
+}
+
+static int
+virSecuritySELinuxRemoveMCSFile(const char *name)
+{
+ char *tmp = NULL;
+ int ret = -1;
+ if (virAsprintf(&tmp, "%s/%s", SELINUX_TRANS_DIR, name) < 0) {
+ virReportOOMError();
+ return -1;
+ }
+ if (unlink(tmp) < 0 && errno != ENOENT) {
+ virReportSystemError(errno,
+ _("Unable to remove MCS file %s"), tmp);
+ goto cleanup;
+ }
+ ret = 0;
+
+cleanup:
+ VIR_FREE(tmp);
+ return ret;
+}
+
/*
* Returns 0 on success, 1 if already reserved, or -1 on fatal error
*/
@@ -1953,7 +2004,7 @@ virSecuritySELinuxReleaseSecurityLabel(virSecurityManagerPtr mgr,
}
VIR_FREE(secdef->imagelabel);
- return 0;
+ return virSecuritySELinuxRemoveMCSFile(def->name);
}
@@ -2047,10 +2098,14 @@ virSecuritySELinuxSetSecurityProcessLabel(virSecurityManagerPtr
mgr ATTRIBUTE_UN
return -1;
}
+ if (virSecurityManagerGetPrivileged(mgr) &&
(virSecuritySELinuxAddMCSFile(def->name, secdef->label) < 0))
+ return -1;
+
if (setexeccon_raw(secdef->label) == -1) {
virReportSystemError(errno,
_("unable to set security context '%s'"),
secdef->label);
+ virSecuritySELinuxRemoveMCSFile(def->name);
if (security_getenforce() == 1)
return -1;
}
--
1.8.2.1