From d755072372e18379bd82134c33b9d2f3bf52647d Mon Sep 17 00:00:00 2001 From: Stefan Berger Date: Fri, 1 Oct 2021 16:50:07 -0400 Subject: [PATCH] swtpm: Make fsync-related errors non-fatal (for libvirt using AppArmor) Only recent libvirt versions have the patch for the AppArmor profile for libvirt to allow fsync after opening a directory for reading. Rather than failing hard on the open-directory-for-reading error, log it once and continue and do not try it again after. This patch addresses the problems seen on Ubuntu related to an older version of libvirt without the AppArmor profile update. - issue #484 - issue #549 - issue #559 Signed-off-by: Stefan Berger --- src/swtpm/swtpm_nvstore_dir.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/swtpm/swtpm_nvstore_dir.c b/src/swtpm/swtpm_nvstore_dir.c index 3a322b5f..7cfc1f6a 100644 --- a/src/swtpm/swtpm_nvstore_dir.c +++ b/src/swtpm/swtpm_nvstore_dir.c @@ -350,6 +350,9 @@ SWTPM_NVRAM_StoreData_Dir(unsigned char *filedata, char filepath[FILENAME_MAX]; /* rooted file path from name */ const char *tpm_state_path = NULL; + static bool do_dir_fsync = true; /* turn off fsync on dir if it fails, + most likely due to AppArmor */ + tpm_state_path = SWTPM_NVRAM_Uri_to_Dir(uri); if (rc == 0) { @@ -434,14 +437,15 @@ SWTPM_NVRAM_StoreData_Dir(unsigned char *filedata, * directory containing the file has also reached disk. For that an * explicit fsync() on a file descriptor for the directory is also needed. */ - if (rc == 0 && fd >= 0) { + if (rc == 0 && fd >= 0 && do_dir_fsync) { TPM_DEBUG(" SWTPM_NVRAM_StoreData: Opening dir %s\n", tpm_state_path); dir_fd = open(tpm_state_path, O_RDONLY); if (dir_fd < 0) { + do_dir_fsync = false; logprintf(STDERR_FILENO, - "SWTPM_NVRAM_StoreData: Error (fatal) opening %s for " - "fsync failed, %s\n", tpm_state_path, strerror(errno)); - rc = TPM_FAIL; + "SWTPM_NVRAM_StoreData: Error opening %s for " + "fsync failed, %s. Continuing but check AppArmor profile.\n", + tpm_state_path, strerror(errno)); } } if (rc == 0 && dir_fd >= 0) {