diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 7d09f33432..f5c21844a4 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -963,6 +963,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 8201022261..470861dc29 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 39736cf3fe..0f21d7af05 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 + * Dan Walsh * */ #include diff --git a/src/security/security_driver.h b/src/security/security_driver.h index d24304cdbd..c68615d7c6 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 e0dd1655b9..8ec4d3e0ef 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 ca27bc6259..f0bf60df6b 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 e979b544f6..b62daf57dc 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 a6f6311a6f..b0bb0a0508 100644 --- a/src/security/security_selinux.c +++ b/src/security/security_selinux.c @@ -1523,6 +1523,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, @@ -1559,4 +1613,6 @@ virSecurityDriver virSecurityDriverSELinux = { SELinuxRestoreSavedStateLabel, SELinuxSetImageFDLabel, + + SELinuxGetSecurityMountOptions, }; diff --git a/src/security/security_stack.c b/src/security/security_stack.c index 2eab38cdce..6ecd099dce 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, };