diff --git a/src/security/security_dac.c b/src/security/security_dac.c index 35b90da03c..38f7ba0c94 100644 --- a/src/security/security_dac.c +++ b/src/security/security_dac.c @@ -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; diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c index 60596ad757..7333a1fccb 100644 --- a/src/security/security_selinux.c +++ b/src/security/security_selinux.c @@ -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,