
On Tue, Feb 10, 2015 at 05:17:34PM +0100, Erik Skultety wrote:
We do have a check for valid per-domain security model, however we still do permit an invalid security model for a domain's device (those which are specified with <source> element). This patch introduces a new function virSecurityManagerCheckAllLabel which compares user specified security model against currently registered security drivers. That being said, it also permits 'none' being specified as a device security model.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1165485 --- src/libvirt_private.syms | 1 + src/qemu/qemu_process.c | 6 ++
missing src/lxc/lxc_process.c
src/security/security_manager.c | 126 ++++++++++++++++++++++++++++++++++++++++ src/security/security_manager.h | 2 + 4 files changed, 135 insertions(+)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 3b4ff41..1b1d891 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -953,6 +953,7 @@ virSecurityDriverLookup;
# security/security_manager.h +virSecurityManagerCheckAllLabel; virSecurityManagerClearSocketLabel; virSecurityManagerGenLabel; virSecurityManagerGetBaseLabel; diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index d5df60d..66ae779 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -4428,6 +4428,10 @@ int qemuProcessStart(virConnectPtr conn, NULL) < 0) goto cleanup;
+ VIR_DEBUG("Checking domain and device security labels"); + if (virSecurityManagerCheckAllLabel(driver->securityManager, vm->def) < 0) + goto cleanup; + /* If you are using a SecurityDriver with dynamic labelling, then generate a security label for isolation */ VIR_DEBUG("Generating domain security label (if required)"); @@ -5424,6 +5428,8 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED, } }
+ if (virSecurityManagerCheckAllLabel(driver->securityManager, vm->def) < 0) + goto error; if (virSecurityManagerGenLabel(driver->securityManager, vm->def) < 0) goto error;
diff --git a/src/security/security_manager.c b/src/security/security_manager.c index 000bc82..32bc9fe 100644 --- a/src/security/security_manager.c +++ b/src/security/security_manager.c @@ -685,6 +685,132 @@ virSecurityManagerReleaseLabel(virSecurityManagerPtr mgr, }
+static int +virSecurityManagerCheckSecurityDiskLabel(virDomainDefPtr def ATTRIBUTE_UNUSED, + virDomainDiskDefPtr disk, + void *opaque) +{ + size_t i, j; + virSecurityManagerPtr mgr = opaque; + virSecurityManagerPtr *sec_managers = NULL; + + if ((sec_managers = virSecurityManagerGetNested(mgr)) == NULL) + return 0; + + for (i = 0; i < disk->src->nseclabels; i++) {
+ if (STREQ_NULLABLE(disk->src->seclabels[i]->model, "none")) + continue; + + for (j = 0; sec_managers[j]; j++) { + if (STREQ_NULLABLE(disk->src->seclabels[i]->model, + sec_managers[j]->drv->name)) { + break;
If you continue; here (or return success if it's in a separate function), the error message below can be unconditional.
+ } + } + if (!sec_managers[j]) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Unable to find security driver for model %s"), + disk->src->seclabels[i]->model); + return -1; + }
This hunk of code is used three times, would be better as a separate function. Jan