From: Daniel Walsh <dwalsh(a)redhat.com>
Some security drivers require special options to be passed to
the mount system call. Add a security driver API for handling
this data.
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
src/libvirt_private.syms | 1 +
src/security/security_dac.c | 7 +++++
src/security/security_driver.c | 3 ++-
src/security/security_driver.h | 4 +++
src/security/security_manager.c | 14 +++++++++-
src/security/security_manager.h | 3 ++-
src/security/security_nop.c | 7 +++++
src/security/security_selinux.c | 56 +++++++++++++++++++++++++++++++++++++++
src/security/security_stack.c | 6 +++++
9 files changed, 98 insertions(+), 3 deletions(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 4f34d25..11e254a 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -961,6 +961,7 @@ virSecurityManagerSetProcessLabel;
virSecurityManagerSetSavedStateLabel;
virSecurityManagerSetSocketLabel;
virSecurityManagerVerify;
+virSecurityManagerGetMountOptions;
# sexpr.h
sexpr_append;
diff --git a/src/security/security_dac.c b/src/security/security_dac.c
index 8201022..470861d 100644
--- a/src/security/security_dac.c
+++ b/src/security/security_dac.c
@@ -717,6 +717,11 @@ virSecurityDACSetImageFDLabel(virSecurityManagerPtr mgr
ATTRIBUTE_UNUSED,
return 0;
}
+static char *virSecurityDACGetMountOptions(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainDefPtr vm ATTRIBUTE_UNUSED) {
+ return NULL;
+}
+
virSecurityDriver virSecurityDriverDAC = {
sizeof(virSecurityDACData),
"virDAC",
@@ -754,4 +759,6 @@ virSecurityDriver virSecurityDriverDAC = {
virSecurityDACRestoreSavedStateLabel,
virSecurityDACSetImageFDLabel,
+
+ virSecurityDACGetMountOptions,
};
diff --git a/src/security/security_driver.c b/src/security/security_driver.c
index 39736cf..0f21d7a 100644
--- a/src/security/security_driver.c
+++ b/src/security/security_driver.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Red Hat, Inc.
+ * Copyright (C) 2008-2012 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -8,6 +8,7 @@
*
* Authors:
* James Morris <jmorris(a)namei.org>
+ * Dan Walsh <dwalsh(a)redhat.com>
*
*/
#include <config.h>
diff --git a/src/security/security_driver.h b/src/security/security_driver.h
index d24304c..c68615d 100644
--- a/src/security/security_driver.h
+++ b/src/security/security_driver.h
@@ -86,6 +86,8 @@ typedef int (*virSecurityDomainSecurityVerify) (virSecurityManagerPtr
mgr,
typedef int (*virSecurityDomainSetImageFDLabel) (virSecurityManagerPtr mgr,
virDomainDefPtr def,
int fd);
+typedef char *(*virSecurityDomainGetMountOptions) (virSecurityManagerPtr mgr,
+ virDomainDefPtr def);
struct _virSecurityDriver {
size_t privateDataLen;
@@ -123,6 +125,8 @@ struct _virSecurityDriver {
virSecurityDomainRestoreSavedStateLabel domainRestoreSavedStateLabel;
virSecurityDomainSetImageFDLabel domainSetSecurityImageFDLabel;
+
+ virSecurityDomainGetMountOptions domainGetSecurityMountOptions;
};
virSecurityDriverPtr virSecurityDriverLookup(const char *name,
diff --git a/src/security/security_manager.c b/src/security/security_manager.c
index e0dd165..ece39cd 100644
--- a/src/security/security_manager.c
+++ b/src/security/security_manager.c
@@ -149,7 +149,6 @@ virSecurityManagerPtr virSecurityManagerNew(const char *name,
requireConfined);
}
-
void *virSecurityManagerGetPrivateData(virSecurityManagerPtr mgr)
{
/* This accesses the memory just beyond mgr, which was allocated
@@ -423,3 +422,16 @@ int virSecurityManagerSetImageFDLabel(virSecurityManagerPtr mgr,
virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
return -1;
}
+
+char *virSecurityManagerGetMountOptions(virSecurityManagerPtr mgr,
+ virDomainDefPtr vm)
+{
+ if (mgr->drv->domainGetSecurityMountOptions)
+ return mgr->drv->domainGetSecurityMountOptions(mgr, vm);
+
+/*
+ I don't think this is an error, these should be optional
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+*/
+ return NULL;
+}
diff --git a/src/security/security_manager.h b/src/security/security_manager.h
index ca27bc6..f0bf60d 100644
--- a/src/security/security_manager.h
+++ b/src/security/security_manager.h
@@ -107,5 +107,6 @@ int virSecurityManagerVerify(virSecurityManagerPtr mgr,
int virSecurityManagerSetImageFDLabel(virSecurityManagerPtr mgr,
virDomainDefPtr def,
int fd);
-
+char *virSecurityManagerGetMountOptions(virSecurityManagerPtr mgr,
+ virDomainDefPtr vm);
#endif /* VIR_SECURITY_MANAGER_H__ */
diff --git a/src/security/security_nop.c b/src/security/security_nop.c
index e979b54..b62daf5 100644
--- a/src/security/security_nop.c
+++ b/src/security/security_nop.c
@@ -164,6 +164,11 @@ static int virSecurityDomainSetFDLabelNop(virSecurityManagerPtr mgr
ATTRIBUTE_UN
return 0;
}
+static char *virSecurityDomainGetMountOptionsNop(virSecurityManagerPtr mgr
ATTRIBUTE_UNUSED,
+ virDomainDefPtr vm ATTRIBUTE_UNUSED) {
+ return NULL;
+}
+
virSecurityDriver virSecurityDriverNop = {
0,
"none",
@@ -200,4 +205,6 @@ virSecurityDriver virSecurityDriverNop = {
virSecurityDomainRestoreSavedStateLabelNop,
virSecurityDomainSetFDLabelNop,
+
+ virSecurityDomainGetMountOptionsNop,
};
diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
index dd6aee9..f7bc567 100644
--- a/src/security/security_selinux.c
+++ b/src/security/security_selinux.c
@@ -1519,6 +1519,60 @@ SELinuxSetImageFDLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
return SELinuxFSetFilecon(fd, secdef->imagelabel);
}
+static char *genImageLabel(virSecurityManagerPtr mgr,
+ virDomainDefPtr def) {
+ const virSecurityLabelDefPtr secdef = &def->seclabel;
+ virSecuritySELinuxDataPtr data = virSecurityManagerGetPrivateData(mgr);
+ const char *range;
+ context_t ctx = NULL;
+ char *label = NULL;
+ const char *mcs = NULL;
+
+ if (secdef->label) {
+ ctx = context_new(secdef->label);
+ if (!ctx) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ range = context_range_get(ctx);
+ if (range) {
+ mcs = strdup(range);
+ if (!mcs) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ label = SELinuxGenNewContext(data->file_context, mcs);
+ if (!label) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ }
+ }
+
+cleanup:
+ context_free(ctx);
+ VIR_FREE(mcs);
+ return label;
+}
+
+static char *SELinuxGetSecurityMountOptions(virSecurityManagerPtr mgr,
+ virDomainDefPtr def) {
+ char *opts = NULL;
+ const virSecurityLabelDefPtr secdef = &def->seclabel;
+
+ if (! secdef->imagelabel)
+ secdef->imagelabel = genImageLabel(mgr,def);
+
+ if (secdef->imagelabel) {
+ virAsprintf(&opts,
+ ",context=\"%s\"",
+ (const char*) secdef->imagelabel);
+ }
+
+ VIR_DEBUG("SELinuxGetSecurityMountOptions imageLabel %s",
secdef->imagelabel);
+ return opts;
+}
+
virSecurityDriver virSecurityDriverSELinux = {
sizeof(virSecuritySELinuxData),
SECURITY_SELINUX_NAME,
@@ -1555,4 +1609,6 @@ virSecurityDriver virSecurityDriverSELinux = {
SELinuxRestoreSavedStateLabel,
SELinuxSetImageFDLabel,
+
+ SELinuxGetSecurityMountOptions,
};
diff --git a/src/security/security_stack.c b/src/security/security_stack.c
index 2eab38c..6ecd099 100644
--- a/src/security/security_stack.c
+++ b/src/security/security_stack.c
@@ -403,6 +403,10 @@ virSecurityStackSetImageFDLabel(virSecurityManagerPtr mgr,
return rc;
}
+static char *virSecurityStackGetMountOptions(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainDefPtr vm ATTRIBUTE_UNUSED) {
+ return NULL;
+}
virSecurityDriver virSecurityDriverStack = {
sizeof(virSecurityStackData),
@@ -440,4 +444,6 @@ virSecurityDriver virSecurityDriverStack = {
virSecurityStackRestoreSavedStateLabel,
virSecurityStackSetImageFDLabel,
+
+ virSecurityStackGetMountOptions,
};
--
1.7.10.1