[libvirt] [PATCHv2 2/2] security_dac: Honor norelabel attribute

Michal Privoznik mprivozn at redhat.com
Fri Apr 4 12:34:23 UTC 2014


The inspiration for this patch comes from a question on the list
asking if there's a way to not label some disks. Well, in DAC driver
there's not. Even if user have requested norelabel:

    <disk type='file' device='disk'>
      <driver name='qemu' type='raw'/>
      <source file='/some/dummy/path/test.bin'>
        <seclabel model='dac' relabel='no'/>
      </source>
      <target dev='vdb' bus='virtio'/>
      <readonly/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/>
    </disk>

the DAC driver ignores this completely.

Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
---
 src/security/security_dac.c | 92 +++++++++++++++++++++++++++++++++++----------
 1 file changed, 73 insertions(+), 19 deletions(-)

diff --git a/src/security/security_dac.c b/src/security/security_dac.c
index 8835d49..f15a0e9 100644
--- a/src/security/security_dac.c
+++ b/src/security/security_dac.c
@@ -286,7 +286,7 @@ virSecurityDACRestoreSecurityFileLabel(const char *path)
 
 
 static int
-virSecurityDACSetSecurityFileLabel(virDomainDiskDefPtr disk ATTRIBUTE_UNUSED,
+virSecurityDACSetSecurityFileLabel(virDomainDiskDefPtr disk,
                                    const char *path,
                                    size_t depth ATTRIBUTE_UNUSED,
                                    void *opaque)
@@ -295,11 +295,23 @@ virSecurityDACSetSecurityFileLabel(virDomainDiskDefPtr disk ATTRIBUTE_UNUSED,
     virSecurityManagerPtr mgr = cbdata->manager;
     virSecurityLabelDefPtr secdef = cbdata->secdef;
     virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+    virSecurityDeviceLabelDefPtr disk_seclabel;
     uid_t user;
     gid_t group;
 
-    if (virSecurityDACGetImageIds(secdef, priv, &user, &group) < 0)
-        return -1;
+    disk_seclabel = virDomainDiskDefGetSecurityLabelDef(disk,
+                                                        SECURITY_DAC_NAME);
+
+    if (disk_seclabel && disk_seclabel->norelabel)
+        return 0;
+
+    if (disk_seclabel && disk_seclabel->label) {
+        if (virParseOwnershipIds(disk_seclabel->label, &user, &group) < 0)
+            return -1;
+    } else {
+        if (virSecurityDACGetImageIds(secdef, priv, &user, &group))
+            return -1;
+    }
 
     return virSecurityDACSetOwnership(path, user, group);
 }
@@ -323,6 +335,9 @@ virSecurityDACSetSecurityImageLabel(virSecurityManagerPtr mgr,
 
     secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_DAC_NAME);
 
+    if (secdef && secdef->norelabel)
+        return 0;
+
     cbdata.manager = mgr;
     cbdata.secdef = secdef;
     return virDomainDiskDefForeachPath(disk,
@@ -339,6 +354,8 @@ virSecurityDACRestoreSecurityImageLabelInt(virSecurityManagerPtr mgr,
                                            int migrated)
 {
     virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+    virSecurityLabelDefPtr secdef;
+    virSecurityDeviceLabelDefPtr disk_seclabel;
     const char *src = virDomainDiskGetSource(disk);
 
     if (!priv->dynamicOwnership)
@@ -347,6 +364,17 @@ virSecurityDACRestoreSecurityImageLabelInt(virSecurityManagerPtr mgr,
     if (virDomainDiskGetType(disk) == VIR_STORAGE_TYPE_NETWORK)
         return 0;
 
+    secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_DAC_NAME);
+
+    if (secdef && secdef->norelabel)
+        return 0;
+
+    disk_seclabel = virDomainDiskDefGetSecurityLabelDef(disk,
+                                                        SECURITY_DAC_NAME);
+
+    if (disk_seclabel && disk_seclabel->norelabel)
+        return 0;
+
     /* Don't restore labels on readoly/shared disks, because
      * other VMs may still be accessing these
      * Alternatively we could iterate over all running
@@ -454,6 +482,9 @@ virSecurityDACSetSecurityHostdevLabel(virSecurityManagerPtr mgr,
     cbdata.manager = mgr;
     cbdata.secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_DAC_NAME);
 
+    if (cbdata.secdef && cbdata.secdef->norelabel)
+        return 0;
+
     switch ((enum virDomainHostdevSubsysType) dev->source.subsys.type) {
     case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: {
         virUSBDevicePtr usb;
@@ -564,15 +595,18 @@ virSecurityDACRestoreSecuritySCSILabel(virSCSIDevicePtr dev ATTRIBUTE_UNUSED,
 
 static int
 virSecurityDACRestoreSecurityHostdevLabel(virSecurityManagerPtr mgr,
-                                          virDomainDefPtr def ATTRIBUTE_UNUSED,
+                                          virDomainDefPtr def,
                                           virDomainHostdevDefPtr dev,
                                           const char *vroot)
 
 {
     virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+    virSecurityLabelDefPtr secdef;
     int ret = -1;
 
-    if (!priv->dynamicOwnership)
+    secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_DAC_NAME);
+
+    if (!priv->dynamicOwnership || (secdef && secdef->norelabel))
         return 0;
 
     if (dev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
@@ -674,6 +708,9 @@ virSecurityDACSetChardevLabel(virSecurityManagerPtr mgr,
         chr_seclabel = virDomainChrDefGetSecurityLabelDef(dev,
                                                           SECURITY_DAC_NAME);
 
+    if (seclabel->norelabel || (chr_seclabel && chr_seclabel->norelabel))
+        return 0;
+
     if (chr_seclabel && chr_seclabel->label) {
         if (virParseOwnershipIds(chr_seclabel->label, &user, &group) < 0)
             return -1;
@@ -727,27 +764,40 @@ virSecurityDACSetChardevLabel(virSecurityManagerPtr mgr,
 
 static int
 virSecurityDACRestoreChardevLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
-                                  virDomainChrSourceDefPtr dev)
+                                  virDomainDefPtr def,
+                                  virDomainChrDefPtr dev,
+                                  virDomainChrSourceDefPtr dev_source)
 {
+    virSecurityLabelDefPtr seclabel;
+    virSecurityDeviceLabelDefPtr chr_seclabel = NULL;
     char *in = NULL, *out = NULL;
     int ret = -1;
 
-    switch ((enum virDomainChrType) dev->type) {
+    seclabel = virDomainDefGetSecurityLabelDef(def, SECURITY_DAC_NAME);
+
+    if (dev)
+        chr_seclabel = virDomainChrDefGetSecurityLabelDef(dev,
+                                                          SECURITY_DAC_NAME);
+
+    if (seclabel->norelabel || (chr_seclabel && chr_seclabel->norelabel))
+        return 0;
+
+    switch ((enum virDomainChrType) dev_source->type) {
     case VIR_DOMAIN_CHR_TYPE_DEV:
     case VIR_DOMAIN_CHR_TYPE_FILE:
-        ret = virSecurityDACRestoreSecurityFileLabel(dev->data.file.path);
+        ret = virSecurityDACRestoreSecurityFileLabel(dev_source->data.file.path);
         break;
 
     case VIR_DOMAIN_CHR_TYPE_PIPE:
-        if ((virAsprintf(&out, "%s.out", dev->data.file.path) < 0) ||
-            (virAsprintf(&in, "%s.in", dev->data.file.path) < 0))
+        if ((virAsprintf(&out, "%s.out", dev_source->data.file.path) < 0) ||
+            (virAsprintf(&in, "%s.in", dev_source->data.file.path) < 0))
             goto done;
         if (virFileExists(in) && virFileExists(out)) {
             if ((virSecurityDACRestoreSecurityFileLabel(out) < 0) ||
                 (virSecurityDACRestoreSecurityFileLabel(in) < 0)) {
                 goto done;
             }
-        } else if (virSecurityDACRestoreSecurityFileLabel(dev->data.file.path) < 0) {
+        } else if (virSecurityDACRestoreSecurityFileLabel(dev_source->data.file.path) < 0) {
             goto done;
         }
         ret = 0;
@@ -775,13 +825,13 @@ virSecurityDACRestoreChardevLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
 
 
 static int
-virSecurityDACRestoreChardevCallback(virDomainDefPtr def ATTRIBUTE_UNUSED,
+virSecurityDACRestoreChardevCallback(virDomainDefPtr def,
                                      virDomainChrDefPtr dev,
                                      void *opaque)
 {
     virSecurityManagerPtr mgr = opaque;
 
-    return virSecurityDACRestoreChardevLabel(mgr, &dev->source);
+    return virSecurityDACRestoreChardevLabel(mgr, def, dev, &dev->source);
 }
 
 
@@ -807,13 +857,14 @@ virSecurityDACSetSecurityTPMFileLabel(virSecurityManagerPtr mgr,
 
 static int
 virSecurityDACRestoreSecurityTPMFileLabel(virSecurityManagerPtr mgr,
+                                          virDomainDefPtr def,
                                           virDomainTPMDefPtr tpm)
 {
     int ret = 0;
 
     switch ((enum virDomainTPMBackendType) tpm->type) {
     case VIR_DOMAIN_TPM_TYPE_PASSTHROUGH:
-        ret = virSecurityDACRestoreChardevLabel(mgr,
+        ret = virSecurityDACRestoreChardevLabel(mgr, def, NULL,
                                           &tpm->data.passthrough.source);
         break;
     case VIR_DOMAIN_TPM_TYPE_LAST:
@@ -830,12 +881,14 @@ virSecurityDACRestoreSecurityAllLabel(virSecurityManagerPtr mgr,
                                       int migrated)
 {
     virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+    virSecurityLabelDefPtr secdef;
     size_t i;
     int rc = 0;
 
-    if (!priv->dynamicOwnership)
-        return 0;
+    secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_DAC_NAME);
 
+    if (!priv->dynamicOwnership || (secdef && secdef->norelabel))
+        return 0;
 
     VIR_DEBUG("Restoring security label on %s migrated=%d",
               def->name, migrated);
@@ -863,6 +916,7 @@ virSecurityDACRestoreSecurityAllLabel(virSecurityManagerPtr mgr,
 
     if (def->tpm) {
         if (virSecurityDACRestoreSecurityTPMFileLabel(mgr,
+                                                      def,
                                                       def->tpm) < 0)
             rc = -1;
     }
@@ -905,11 +959,11 @@ virSecurityDACSetSecurityAllLabel(virSecurityManagerPtr mgr,
     uid_t user;
     gid_t group;
 
-    if (!priv->dynamicOwnership)
-        return 0;
-
     secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_DAC_NAME);
 
+    if (!priv->dynamicOwnership || (secdef && secdef->norelabel))
+        return 0;
+
     for (i = 0; i < def->ndisks; i++) {
         /* XXX fixme - we need to recursively label the entire tree :-( */
         if (virDomainDiskGetType(def->disks[i]) == VIR_STORAGE_TYPE_DIR)
-- 
1.9.0




More information about the libvir-list mailing list