165 lines
6.8 KiB
Diff
165 lines
6.8 KiB
Diff
|
|
From b3a5dde7f5a8874084f978ea698a749d858e769a Mon Sep 17 00:00:00 2001
|
||
|
|
From: Stefan Berger <stefanb@linux.vnet.ibm.com>
|
||
|
|
Date: Fri, 2 Oct 2020 16:29:18 -0400
|
||
|
|
Subject: [PATCH 1/5] swtpm: Write state files atomically using file renaming
|
||
|
|
|
||
|
|
To support writing state files atomically we first write into
|
||
|
|
a temporary file and then rename it.
|
||
|
|
|
||
|
|
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
|
||
|
|
---
|
||
|
|
src/swtpm/swtpm_nvfile.c | 59 ++++++++++++++++++++++++++++++----------
|
||
|
|
1 file changed, 45 insertions(+), 14 deletions(-)
|
||
|
|
|
||
|
|
diff --git a/src/swtpm/swtpm_nvfile.c b/src/swtpm/swtpm_nvfile.c
|
||
|
|
index 6f3f937..3b928d0 100644
|
||
|
|
--- a/src/swtpm/swtpm_nvfile.c
|
||
|
|
+++ b/src/swtpm/swtpm_nvfile.c
|
||
|
|
@@ -132,7 +132,8 @@ static unsigned char *g_ivec;
|
||
|
|
static TPM_RESULT SWTPM_NVRAM_GetFilenameForName(char *filename,
|
||
|
|
size_t bufsize,
|
||
|
|
uint32_t tpm_number,
|
||
|
|
- const char *name);
|
||
|
|
+ const char *name,
|
||
|
|
+ bool is_tempfile);
|
||
|
|
|
||
|
|
static TPM_RESULT SWTPM_NVRAM_EncryptData(const encryptionkey *key,
|
||
|
|
tlv_data *td,
|
||
|
|
@@ -312,7 +313,7 @@ SWTPM_NVRAM_LoadData(unsigned char **data, /* freed by caller */
|
||
|
|
if (rc == 0) {
|
||
|
|
/* map name to the rooted filename */
|
||
|
|
rc = SWTPM_NVRAM_GetFilenameForName(filename, sizeof(filename),
|
||
|
|
- tpm_number, name);
|
||
|
|
+ tpm_number, name, false);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (rc == 0) {
|
||
|
|
@@ -473,6 +474,7 @@ SWTPM_NVRAM_StoreData_Intern(const unsigned char *data,
|
||
|
|
uint32_t lrc;
|
||
|
|
int irc;
|
||
|
|
FILE *file = NULL;
|
||
|
|
+ char tmpfile[FILENAME_MAX]; /* rooted temporary file */
|
||
|
|
char filename[FILENAME_MAX]; /* rooted file name from name */
|
||
|
|
unsigned char *filedata = NULL;
|
||
|
|
uint32_t filedata_length = 0;
|
||
|
|
@@ -484,16 +486,24 @@ SWTPM_NVRAM_StoreData_Intern(const unsigned char *data,
|
||
|
|
if (rc == 0) {
|
||
|
|
/* map name to the rooted filename */
|
||
|
|
rc = SWTPM_NVRAM_GetFilenameForName(filename, sizeof(filename),
|
||
|
|
- tpm_number, name);
|
||
|
|
+ tpm_number, name, false);
|
||
|
|
}
|
||
|
|
+
|
||
|
|
+ if (rc == 0) {
|
||
|
|
+ /* map name to the rooted temporary file */
|
||
|
|
+ rc = SWTPM_NVRAM_GetFilenameForName(tmpfile, sizeof(tmpfile),
|
||
|
|
+ tpm_number, name, true);
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+
|
||
|
|
if (rc == 0) {
|
||
|
|
/* open the file */
|
||
|
|
- TPM_DEBUG(" SWTPM_NVRAM_StoreData: Opening file %s\n", filename);
|
||
|
|
- file = fopen(filename, "wb"); /* closed @1 */
|
||
|
|
+ TPM_DEBUG(" SWTPM_NVRAM_StoreData: Opening file %s\n", tmpfile);
|
||
|
|
+ file = fopen(tmpfile, "wb"); /* closed @1 */
|
||
|
|
if (file == NULL) {
|
||
|
|
logprintf(STDERR_FILENO,
|
||
|
|
"SWTPM_NVRAM_StoreData: Error (fatal) opening %s for "
|
||
|
|
- "write failed, %s\n", filename, strerror(errno));
|
||
|
|
+ "write failed, %s\n", tmpfile, strerror(errno));
|
||
|
|
rc = TPM_FAIL;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
@@ -502,7 +512,7 @@ SWTPM_NVRAM_StoreData_Intern(const unsigned char *data,
|
||
|
|
if (fchmod(fileno(file), tpmstate_get_mode()) < 0) {
|
||
|
|
logprintf(STDERR_FILENO,
|
||
|
|
"SWTPM_NVRAM_StoreData: Could not fchmod %s : %s\n",
|
||
|
|
- filename, strerror(errno));
|
||
|
|
+ tmpfile, strerror(errno));
|
||
|
|
rc = TPM_FAIL;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
@@ -548,7 +558,7 @@ SWTPM_NVRAM_StoreData_Intern(const unsigned char *data,
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (file != NULL) {
|
||
|
|
- TPM_DEBUG(" SWTPM_NVRAM_StoreData: Closing file %s\n", filename);
|
||
|
|
+ TPM_DEBUG(" SWTPM_NVRAM_StoreData: Closing file %s\n", tmpfile);
|
||
|
|
irc = fclose(file); /* @1 */
|
||
|
|
if (irc != 0) {
|
||
|
|
logprintf(STDERR_FILENO,
|
||
|
|
@@ -556,12 +566,24 @@ SWTPM_NVRAM_StoreData_Intern(const unsigned char *data,
|
||
|
|
rc = TPM_FAIL;
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
- TPM_DEBUG(" SWTPM_NVRAM_StoreData: Closed file %s\n", filename);
|
||
|
|
+ TPM_DEBUG(" SWTPM_NVRAM_StoreData: Closed file %s\n", tmpfile);
|
||
|
|
+ }
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ if (rc == 0 && file != NULL) {
|
||
|
|
+ irc = rename(tmpfile, filename);
|
||
|
|
+ if (irc != 0) {
|
||
|
|
+ logprintf(STDERR_FILENO,
|
||
|
|
+ "SWTPM_NVRAM_StoreData: Error (fatal) renaming file: %s\n",
|
||
|
|
+ strerror(errno));
|
||
|
|
+ rc = TPM_FAIL;
|
||
|
|
+ } else {
|
||
|
|
+ TPM_DEBUG(" SWTPM_NVRAM_StoreData: Renamed file to %s\n", filename);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (rc != 0 && file != NULL) {
|
||
|
|
- unlink(filename);
|
||
|
|
+ unlink(tmpfile);
|
||
|
|
}
|
||
|
|
|
||
|
|
tlv_data_free(td, td_len);
|
||
|
|
@@ -585,12 +607,16 @@ TPM_RESULT SWTPM_NVRAM_StoreData(const unsigned char *data,
|
||
|
|
The filename is of the form:
|
||
|
|
|
||
|
|
state_directory/tpm_number.name
|
||
|
|
+
|
||
|
|
+ A temporary filename used to write to may be created. It shold be rename()'d to
|
||
|
|
+ the non-temporary filename.
|
||
|
|
*/
|
||
|
|
|
||
|
|
static TPM_RESULT SWTPM_NVRAM_GetFilenameForName(char *filename, /* output: rooted filename */
|
||
|
|
size_t bufsize,
|
||
|
|
uint32_t tpm_number,
|
||
|
|
- const char *name) /* input: abstract name */
|
||
|
|
+ const char *name, /* input: abstract name */
|
||
|
|
+ bool is_tempfile) /* input: is temporary file? */
|
||
|
|
{
|
||
|
|
TPM_RESULT res = TPM_SUCCESS;
|
||
|
|
int n;
|
||
|
|
@@ -606,8 +632,13 @@ static TPM_RESULT SWTPM_NVRAM_GetFilenameForName(char *filename, /* outpu
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
- n = snprintf(filename, bufsize, "%s/tpm%s-%02lx.%s",
|
||
|
|
- state_directory, suffix, (unsigned long)tpm_number, name);
|
||
|
|
+ if (is_tempfile) {
|
||
|
|
+ n = snprintf(filename, bufsize, "%s/TMP%s-%02lx.%s",
|
||
|
|
+ state_directory, suffix, (unsigned long)tpm_number, name);
|
||
|
|
+ } else {
|
||
|
|
+ n = snprintf(filename, bufsize, "%s/tpm%s-%02lx.%s",
|
||
|
|
+ state_directory, suffix, (unsigned long)tpm_number, name);
|
||
|
|
+ }
|
||
|
|
if ((size_t)n > bufsize) {
|
||
|
|
res = TPM_FAIL;
|
||
|
|
}
|
||
|
|
@@ -638,7 +669,7 @@ TPM_RESULT SWTPM_NVRAM_DeleteName(uint32_t tpm_number,
|
||
|
|
TPM_DEBUG(" SWTPM_NVRAM_DeleteName: Name %s\n", name);
|
||
|
|
/* map name to the rooted filename */
|
||
|
|
rc = SWTPM_NVRAM_GetFilenameForName(filename, sizeof(filename),
|
||
|
|
- tpm_number, name);
|
||
|
|
+ tpm_number, name, false);
|
||
|
|
if (rc == 0) {
|
||
|
|
irc = remove(filename);
|
||
|
|
if ((irc != 0) && /* if the remove failed */
|
||
|
|
--
|
||
|
|
2.27.0
|
||
|
|
|