diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index a241d5153bdf8f023ac4af554efd453131c5434f..c07a5613f1c3bc3279ac8b70033b983f97fafade 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -956,6 +956,7 @@ virSecurityDriverLookup; # security/security_manager.h +virSecurityManagerCheckAllLabel; virSecurityManagerClearSocketLabel; virSecurityManagerGenLabel; virSecurityManagerGetBaseLabel; diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c index 19ea7f314fb35113a2ce5e0da64aa885c0a9e071..52b7f41357d9e132b7bbd79db15625d280413389 100644 --- a/src/lxc/lxc_process.c +++ b/src/lxc/lxc_process.c @@ -1135,6 +1135,9 @@ int virLXCProcessStart(virConnectPtr conn, vm->def->seclabels[0]->type == VIR_DOMAIN_SECLABEL_DEFAULT) vm->def->seclabels[0]->type = VIR_DOMAIN_SECLABEL_NONE; + if (virSecurityManagerCheckAllLabel(driver->securityManager, vm->def) < 0) + goto cleanup; + if (virSecurityManagerGenLabel(driver->securityManager, vm->def) < 0) { virDomainAuditSecurityLabel(vm, false); goto cleanup; diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 43a64a16b2663cf2fcf67dce493f0bd13ed43964..1d4e957729880a67f2c09b1f547c1299223b85e8 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -4488,6 +4488,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)"); @@ -5488,6 +5492,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 302f54d2b394572363832f2a142a263c460f3a12..4b5132f8d0ce77d60ea99c426b5fd997bc123dd5 100644 --- a/src/security/security_manager.c +++ b/src/security/security_manager.c @@ -703,6 +703,90 @@ virSecurityManagerReleaseLabel(virSecurityManagerPtr mgr, } +static int virSecurityManagerCheckModel(virSecurityManagerPtr mgr, + char *secmodel) +{ + size_t i; + virSecurityManagerPtr *sec_managers = NULL; + + if ((sec_managers = virSecurityManagerGetNested(mgr)) == NULL) + return -1; + + if (STREQ_NULLABLE(secmodel, "none")) + return 0; + + for (i = 0; sec_managers[i]; i++) { + if (STREQ_NULLABLE(secmodel, sec_managers[i]->drv->name)) + return 0; + } + + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Unable to find security driver for model %s"), + secmodel); + return -1; +} + + +static int +virSecurityManagerCheckDiskLabel(virSecurityManagerPtr mgr, + virDomainDiskDefPtr disk) +{ + size_t i; + + for (i = 0; i < disk->src->nseclabels; i++) { + if (virSecurityManagerCheckModel(mgr, disk->src->seclabels[i]->model) < 0) + return -1; + } + + return 0; +} + + +static int +virSecurityManagerCheckChardevLabel(virSecurityManagerPtr mgr, + virDomainChrDefPtr dev) +{ + size_t i; + + for (i = 0; i < dev->nseclabels; i++) { + if (virSecurityManagerCheckModel(mgr, dev->seclabels[i]->model) < 0) + return -1; + } + + return 0; +} + + +static int +virSecurityManagerCheckChardevCallback(virDomainDefPtr def ATTRIBUTE_UNUSED, + virDomainChrDefPtr dev, + void *opaque) +{ + virSecurityManagerPtr mgr = opaque; + return virSecurityManagerCheckChardevLabel(mgr, dev); +} + + +int virSecurityManagerCheckAllLabel(virSecurityManagerPtr mgr, + virDomainDefPtr vm) +{ + size_t i; + + for (i = 0; i < vm->ndisks; i++) { + if (virSecurityManagerCheckDiskLabel(mgr, vm->disks[i]) < 0) + return -1; + } + + if (virDomainChrDefForeach(vm, + true, + virSecurityManagerCheckChardevCallback, + mgr) < 0) + return -1; + + return 0; +} + + int virSecurityManagerSetAllLabel(virSecurityManagerPtr mgr, virDomainDefPtr vm, diff --git a/src/security/security_manager.h b/src/security/security_manager.h index 156f88291085205cc95c19540a745eca6897ba45..13468db3997bc28744871a25132677e9c7acdf54 100644 --- a/src/security/security_manager.h +++ b/src/security/security_manager.h @@ -111,6 +111,8 @@ int virSecurityManagerReserveLabel(virSecurityManagerPtr mgr, pid_t pid); int virSecurityManagerReleaseLabel(virSecurityManagerPtr mgr, virDomainDefPtr sec); +int virSecurityManagerCheckAllLabel(virSecurityManagerPtr mgr, + virDomainDefPtr sec); int virSecurityManagerSetAllLabel(virSecurityManagerPtr mgr, virDomainDefPtr sec, const char *stdin_path);