]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/libvirt.git/commitdiff
Add SELinux and DAC labeling support for TPM passthrough
authorStefan Berger <stefanb@linux.vnet.ibm.com>
Fri, 12 Apr 2013 20:55:46 +0000 (16:55 -0400)
committerStefan Berger <stefanb@us.ibm.com>
Fri, 12 Apr 2013 20:55:46 +0000 (16:55 -0400)
Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
Reviewed-by: Corey Bryant <coreyb@linux.vnet.ibm.com>
Tested-by: Corey Bryant <coreyb@linux.vnet.ibm.com>
src/security/security_dac.c
src/security/security_selinux.c

index 35b90da03c3e501e477f77971603f2243ae0fc0b..38f7ba0c94a57d0bd52758782cff227599d5c532 100644 (file)
@@ -715,6 +715,46 @@ virSecurityDACRestoreChardevCallback(virDomainDefPtr def ATTRIBUTE_UNUSED,
 }
 
 
+static int
+virSecurityDACSetSecurityTPMFileLabel(virSecurityManagerPtr mgr,
+                                      virDomainDefPtr def,
+                                      virDomainTPMDefPtr tpm)
+{
+    int ret = 0;
+
+    switch (tpm->type) {
+    case VIR_DOMAIN_TPM_TYPE_PASSTHROUGH:
+        ret = virSecurityDACSetChardevLabel(mgr, def,
+                                            &tpm->data.passthrough.source);
+        break;
+    case VIR_DOMAIN_TPM_TYPE_LAST:
+        break;
+    }
+
+    return ret;
+}
+
+
+static int
+virSecurityDACRestoreSecurityTPMFileLabel(
+                                   virSecurityManagerPtr mgr,
+                                   virDomainTPMDefPtr tpm)
+{
+    int ret = 0;
+
+    switch (tpm->type) {
+    case VIR_DOMAIN_TPM_TYPE_PASSTHROUGH:
+        ret = virSecurityDACRestoreChardevLabel(mgr,
+                                          &tpm->data.passthrough.source);
+        break;
+    case VIR_DOMAIN_TPM_TYPE_LAST:
+        break;
+    }
+
+    return ret;
+}
+
+
 static int
 virSecurityDACRestoreSecurityAllLabel(virSecurityManagerPtr mgr,
                                       virDomainDefPtr def,
@@ -752,6 +792,12 @@ virSecurityDACRestoreSecurityAllLabel(virSecurityManagerPtr mgr,
                                mgr) < 0)
         rc = -1;
 
+    if (def->tpm) {
+        if (virSecurityDACRestoreSecurityTPMFileLabel(mgr,
+                                                      def->tpm) < 0)
+            rc = -1;
+    }
+
     if (def->os.kernel &&
         virSecurityDACRestoreSecurityFileLabel(def->os.kernel) < 0)
         rc = -1;
@@ -815,6 +861,13 @@ virSecurityDACSetSecurityAllLabel(virSecurityManagerPtr mgr,
                                mgr) < 0)
         return -1;
 
+    if (def->tpm) {
+        if (virSecurityDACSetSecurityTPMFileLabel(mgr,
+                                                  def,
+                                                  def->tpm) < 0)
+            return -1;
+    }
+
     if (virSecurityDACGetImageIds(def, priv, &user, &group))
         return -1;
 
index 60596ad757267eaad73d517429614071faa88ad4..7333a1fccb0aadcb866c4e5de46a21054c770ae1 100644 (file)
@@ -45,6 +45,7 @@
 #include "virrandom.h"
 #include "virutil.h"
 #include "virconf.h"
+#include "virtpm.h"
 
 #define VIR_FROM_THIS VIR_FROM_SECURITY
 
@@ -76,6 +77,12 @@ struct _virSecuritySELinuxCallbackData {
 #define SECURITY_SELINUX_VOID_DOI       "0"
 #define SECURITY_SELINUX_NAME "selinux"
 
+static int
+virSecuritySELinuxRestoreSecurityTPMFileLabelInt(virSecurityManagerPtr mgr,
+                                                 virDomainDefPtr def,
+                                                 virDomainTPMDefPtr tpm);
+
+
 /*
  * Returns 0 on success, 1 if already reserved, or -1 on fatal error
  */
@@ -1062,6 +1069,83 @@ err:
     return rc;
 }
 
+
+static int
+virSecuritySELinuxSetSecurityTPMFileLabel(virSecurityManagerPtr mgr,
+                                          virDomainDefPtr def,
+                                          virDomainTPMDefPtr tpm)
+{
+    int rc;
+    virSecurityLabelDefPtr seclabel;
+    char *cancel_path;
+    const char *tpmdev;
+
+    seclabel = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
+    if (seclabel == NULL)
+        return -1;
+
+    switch (tpm->type) {
+    case VIR_DOMAIN_TPM_TYPE_PASSTHROUGH:
+        tpmdev = tpm->data.passthrough.source.data.file.path;
+        rc = virSecuritySELinuxSetFilecon(tpmdev, seclabel->imagelabel);
+        if (rc < 0)
+            return -1;
+
+        if ((cancel_path = virTPMCreateCancelPath(tpmdev)) != NULL) {
+            rc = virSecuritySELinuxSetFilecon(cancel_path,
+                                              seclabel->imagelabel);
+            VIR_FREE(cancel_path);
+            if (rc < 0) {
+                virSecuritySELinuxRestoreSecurityTPMFileLabelInt(mgr, def,
+                                                                 tpm);
+                return -1;
+            }
+        } else {
+            return -1;
+        }
+        break;
+    case VIR_DOMAIN_TPM_TYPE_LAST:
+        break;
+    }
+
+    return 0;
+}
+
+
+static int
+virSecuritySELinuxRestoreSecurityTPMFileLabelInt(virSecurityManagerPtr mgr,
+                                                 virDomainDefPtr def,
+                                                 virDomainTPMDefPtr tpm)
+{
+    int rc = 0;
+    virSecurityLabelDefPtr seclabel;
+    char *cancel_path;
+    const char *tpmdev;
+
+    seclabel = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
+    if (seclabel == NULL)
+        return -1;
+
+    switch (tpm->type) {
+    case VIR_DOMAIN_TPM_TYPE_PASSTHROUGH:
+        tpmdev = tpm->data.passthrough.source.data.file.path;
+        rc = virSecuritySELinuxRestoreSecurityFileLabel(mgr, tpmdev);
+
+        if ((cancel_path = virTPMCreateCancelPath(tpmdev)) != NULL) {
+            if (virSecuritySELinuxRestoreSecurityFileLabel(mgr,
+                                  cancel_path) < 0)
+                rc = -1;
+            VIR_FREE(cancel_path);
+        }
+        break;
+    case VIR_DOMAIN_TPM_TYPE_LAST:
+        break;
+    }
+
+    return rc;
+}
+
+
 static int
 virSecuritySELinuxRestoreSecurityImageLabelInt(virSecurityManagerPtr mgr,
                                                virDomainDefPtr def,
@@ -1734,6 +1818,12 @@ virSecuritySELinuxRestoreSecurityAllLabel(virSecurityManagerPtr mgr,
     if (secdef->norelabel || data->skipAllLabel)
         return 0;
 
+    if (def->tpm) {
+        if (virSecuritySELinuxRestoreSecurityTPMFileLabelInt(mgr, def,
+                                                             def->tpm) < 0)
+            rc = -1;
+    }
+
     for (i = 0 ; i < def->nhostdevs ; i++) {
         if (virSecuritySELinuxRestoreSecurityHostdevLabel(mgr,
                                                           def,
@@ -2148,6 +2238,11 @@ virSecuritySELinuxSetSecurityAllLabel(virSecurityManagerPtr mgr,
                                                       NULL) < 0)
             return -1;
     }
+    if (def->tpm) {
+        if (virSecuritySELinuxSetSecurityTPMFileLabel(mgr, def,
+                                                      def->tpm) < 0)
+            return -1;
+    }
 
     if (virDomainChrDefForeach(def,
                                true,