[RFC PATCH V1 2/5] tpm: Extend existing security handlers for TPM storage file

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch extends the SELinux and DAC security handlers with support
for the TPM's storage file.

If the user did not provide an explicit file for TPM data storage, then
a dummy-file is created in the drivers here and labeled. Athis is necessary
since the creation of the TPM's QCoW2 storage file happens later.

There is no code for AppArmor. I am not sure whether it needs explicit
support. Obviously I haven't tested it with AppArmor.


Signed-off-by: Stefan Berger <stefanb@xxxxxxxxxxxxxxxxxx>

---
 src/security/security_dac.c     |  102 ++++++++++++++++++++++++++++++++++++++++
 src/security/security_selinux.c |  100 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 202 insertions(+)

Index: libvirt-acl/src/security/security_selinux.c
===================================================================
--- libvirt-acl.orig/src/security/security_selinux.c
+++ libvirt-acl/src/security/security_selinux.c
@@ -522,6 +522,94 @@ SELinuxRestoreSecurityImageLabel(virSecu
 
 
 static int
+SELinuxSetSecurityTPMFileLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+                               virDomainObjPtr vm,
+                               virDomainTPMDefPtr tpm)
+{
+    int rc;
+    char *path;
+    struct stat statbuf;
+    FILE *f;
+    const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
+
+    if (secdef->type == VIR_DOMAIN_SECLABEL_STATIC)
+        return 0;
+
+    switch (tpm->type) {
+    case VIR_DOMAIN_TPM_TYPE_BUILTIN:
+        path = virDomainTPMGetStorageFilename(tpm,
+                                              vm->def->uuid);
+        if (stat(path, &statbuf) == -1 && errno == ENOENT) {
+            f = fopen(path, "w");
+            VIR_FORCE_FCLOSE(f);
+        }
+        rc = SELinuxSetFilecon(path, vm->def->seclabel.imagelabel);
+        VIR_FREE(path);
+        if (rc < 0)
+            return -1;
+    break;
+
+    case VIR_DOMAIN_TPM_TYPE_LAST:
+    break;
+    }
+
+    return 0;
+}
+
+
+static int
+SELinuxRestoreSecurityTPMFileLabelInt(
+                                   virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+                                   virDomainObjPtr vm,
+                                   virDomainTPMDefPtr tpm,
+                                   int migrated)
+{
+    int rc = 0;
+    char *path;
+    struct stat statbuf;
+    const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
+
+    if (secdef->type == VIR_DOMAIN_SECLABEL_STATIC)
+        return 0;
+
+    switch (tpm->type) {
+    case VIR_DOMAIN_TPM_TYPE_BUILTIN:
+        path = virDomainTPMGetStorageFilename(tpm,
+                                              vm->def->uuid);
+        if (stat(path, &statbuf) == 0 && statbuf.st_size == 0)
+            unlink(path);
+
+        /* If we have a shared FS & doing migrated, we must not
+         * change ownership, because that kills access on the
+         * destination host which is sub-optimal for the guest
+         * VM's I/O attempts :-)
+        */
+        if (migrated) {
+            rc = virStorageFileIsSharedFS(path);
+            if (rc < 0) {
+                VIR_FREE(path);
+                return -1;
+            }
+            if (rc == 1) {
+                VIR_DEBUG("Skipping image label restore on %s because FS is shared",
+                          path);
+                VIR_FREE(path);
+                return 0;
+            }
+        }
+        rc = SELinuxRestoreSecurityFileLabel(path);
+        VIR_FREE(path);
+    break;
+
+    case VIR_DOMAIN_TPM_TYPE_LAST:
+    break;
+    }
+
+    return rc;
+}
+
+
+static int
 SELinuxSetSecurityFileLabel(virDomainDiskDefPtr disk,
                             const char *path,
                             size_t depth,
@@ -854,6 +942,14 @@ SELinuxRestoreSecurityAllLabel(virSecuri
     if (secdef->type == VIR_DOMAIN_SECLABEL_STATIC)
         return 0;
 
+    if (vm->def->tpm) {
+        if (SELinuxRestoreSecurityTPMFileLabelInt(mgr,
+                                                  vm,
+                                                  vm->def->tpm,
+                                                  migrated) < 0)
+            rc = -1;
+    }
+
     for (i = 0 ; i < vm->def->nhostdevs ; i++) {
         if (SELinuxRestoreSecurityHostdevLabel(mgr,
                                                vm,
@@ -1171,6 +1267,10 @@ SELinuxSetSecurityAllLabel(virSecurityMa
                                            vm->def->hostdevs[i]) < 0)
             return -1;
     }
+    if (vm->def->tpm)
+        if (SELinuxSetSecurityTPMFileLabel(mgr,
+                                           vm, vm->def->tpm) < 0)
+            return -1;
 
     if (virDomainChrDefForeach(vm->def,
                                true,
Index: libvirt-acl/src/security/security_dac.c
===================================================================
--- libvirt-acl.orig/src/security/security_dac.c
+++ libvirt-acl/src/security/security_dac.c
@@ -31,6 +31,7 @@
 #include "pci.h"
 #include "hostusb.h"
 #include "storage_file.h"
+#include "files.h"
 
 #define VIR_FROM_THIS VIR_FROM_SECURITY
 
@@ -243,6 +244,94 @@ virSecurityDACRestoreSecurityImageLabel(
 
 
 static int
+virSecurityDACSetSecurityTPMFileLabel(virSecurityManagerPtr mgr,
+                                      virDomainObjPtr vm,
+                                      virDomainTPMDefPtr tpm)
+{
+    int rc;
+    char *path;
+    struct stat statbuf;
+    FILE *f;
+    virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+
+    if (!priv->dynamicOwnership)
+        return 0;
+
+    switch (tpm->type) {
+    case VIR_DOMAIN_TPM_TYPE_BUILTIN:
+        path = virDomainTPMGetStorageFilename(tpm,
+                                              vm->def->uuid);
+        if (stat(path, &statbuf) == -1 && errno == ENOENT) {
+            f = fopen(path, "w");
+            VIR_FORCE_FCLOSE(f);
+        }
+        rc = virSecurityDACSetOwnership(path, priv->user, priv->group);
+        VIR_FREE(path);
+        if (rc < 0)
+            return -1;
+    break;
+
+    case VIR_DOMAIN_TPM_TYPE_LAST:
+    break;
+    }
+
+    return 0;
+}
+
+
+static int
+virSecurityDACRestoreSecurityTPMFileLabelInt(
+                                   virSecurityManagerPtr mgr,
+                                   virDomainObjPtr vm,
+                                   virDomainTPMDefPtr tpm,
+                                   int migrated)
+{
+    int rc = 0;
+    char *path;
+    struct stat statbuf;
+    virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+
+    if (!priv->dynamicOwnership)
+        return 0;
+
+    switch (tpm->type) {
+    case VIR_DOMAIN_TPM_TYPE_BUILTIN:
+        path = virDomainTPMGetStorageFilename(tpm,
+                                              vm->def->uuid);
+        if (stat(path, &statbuf) == 0 && statbuf.st_size == 0)
+            unlink(path);
+
+        /* If we have a shared FS & doing migrated, we must not
+         * change ownership, because that kills access on the
+         * destination host which is sub-optimal for the guest
+         * VM's I/O attempts :-)
+        */
+        if (migrated) {
+            rc = virStorageFileIsSharedFS(path);
+            if (rc < 0) {
+                VIR_FREE(path);
+                return -1;
+            }
+            if (rc == 1) {
+                VIR_DEBUG("Skipping image label restore on %s because FS is shared",
+                          path);
+                VIR_FREE(path);
+                return 0;
+            }
+        }
+        rc = virSecurityDACRestoreSecurityFileLabel(path);
+        VIR_FREE(path);
+    break;
+
+    case VIR_DOMAIN_TPM_TYPE_LAST:
+    break;
+    }
+
+    return rc;
+}
+
+
+static int
 virSecurityDACSetSecurityPCILabel(pciDevice *dev ATTRIBUTE_UNUSED,
                                   const char *file,
                                   void *opaque)
@@ -492,6 +581,14 @@ virSecurityDACRestoreSecurityAllLabel(vi
     VIR_DEBUG("Restoring security label on %s migrated=%d",
               vm->def->name, migrated);
 
+    if (vm->def->tpm) {
+        if (virSecurityDACRestoreSecurityTPMFileLabelInt(mgr,
+                                                         vm,
+                                                         vm->def->tpm,
+                                                         migrated) < 0)
+            rc = -1;
+    }
+
     for (i = 0 ; i < vm->def->nhostdevs ; i++) {
         if (virSecurityDACRestoreSecurityHostdevLabel(mgr,
                                                       vm,
@@ -561,6 +658,11 @@ virSecurityDACSetSecurityAllLabel(virSec
                                                   vm->def->hostdevs[i]) < 0)
             return -1;
     }
+    if (vm->def->tpm)
+        if (virSecurityDACSetSecurityTPMFileLabel(mgr,
+                                                  vm,
+                                                  vm->def->tpm) < 0)
+            return -1;
 
     if (virDomainChrDefForeach(vm->def,
                                true,

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list


[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]