]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/libvirt.git/commitdiff
security: introduce virSecurityManagerCheckAllLabel function
authorErik Skultety <eskultet@redhat.com>
Thu, 12 Feb 2015 17:32:40 +0000 (18:32 +0100)
committerJán Tomko <jtomko@redhat.com>
Fri, 13 Feb 2015 13:37:54 +0000 (14:37 +0100)
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
Signed-off-by: Ján Tomko <jtomko@redhat.com>
src/libvirt_private.syms
src/lxc/lxc_process.c
src/qemu/qemu_process.c
src/security/security_manager.c
src/security/security_manager.h

index a241d5153bdf8f023ac4af554efd453131c5434f..c07a5613f1c3bc3279ac8b70033b983f97fafade 100644 (file)
@@ -956,6 +956,7 @@ virSecurityDriverLookup;
 
 
 # security/security_manager.h
+virSecurityManagerCheckAllLabel;
 virSecurityManagerClearSocketLabel;
 virSecurityManagerGenLabel;
 virSecurityManagerGetBaseLabel;
index 19ea7f314fb35113a2ce5e0da64aa885c0a9e071..52b7f41357d9e132b7bbd79db15625d280413389 100644 (file)
@@ -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;
index 43a64a16b2663cf2fcf67dce493f0bd13ed43964..1d4e957729880a67f2c09b1f547c1299223b85e8 100644 (file)
@@ -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;
 
index 302f54d2b394572363832f2a142a263c460f3a12..4b5132f8d0ce77d60ea99c426b5fd997bc123dd5 100644 (file)
@@ -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,
index 156f88291085205cc95c19540a745eca6897ba45..13468db3997bc28744871a25132677e9c7acdf54 100644 (file)
@@ -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);