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

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



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 linux vnet ibm com>

---
 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,


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