swtpm: Factor-out code to file_write

Move the file writing parts from SWTPM_NVRAM_StoreData_Dir into file_write.

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
This commit is contained in:
Stefan Berger 2025-04-25 23:32:13 -04:00 committed by Stefan Berger
parent 7d2ee6ebc2
commit 9e2c3a1dec
3 changed files with 53 additions and 56 deletions

View File

@ -369,15 +369,13 @@ SWTPM_NVRAM_StoreData_Dir(unsigned char *filedata,
const char *uri)
{
TPM_RESULT rc = 0;
int fd = -1;
uint32_t lrc;
int irc;
char tmpfile[FILENAME_MAX]; /* rooted temporary file path */
char filepath[FILENAME_MAX]; /* rooted file path from name */
const char *tpm_state_path = NULL;
bool mode_is_default = true;
mode_t mode;
mode_t orig_umask = 0;
ssize_t n;
tpm_state_path = SWTPM_NVRAM_Uri_to_Dir(uri);
@ -396,75 +394,28 @@ SWTPM_NVRAM_StoreData_Dir(unsigned char *filedata,
}
if (rc == 0) {
/* open the file */
TPM_DEBUG(" SWTPM_NVRAM_StoreData: Opening file %s\n", tmpfile);
/*
* If a new file is created at this point with user-requested mode bits
* then use a temporary umask of 0 to have these mode bits set.
* In the more frequent file truncation case the mode bits will also be
* changed to what the user requested.
*/
mode = tpmstate_get_mode(&mode_is_default);
if (!mode_is_default)
orig_umask = umask(0);
fd = open(tmpfile, O_WRONLY|O_CREAT|O_TRUNC|O_NOFOLLOW,
mode); /* closed @1 */
if (!mode_is_default)
umask(orig_umask);
if (fd < 0) {
n = file_write(tmpfile, O_WRONLY|O_CREAT|O_TRUNC|O_NOFOLLOW, mode,
!mode_is_default, filedata, filedata_length);
if (n < 0) {
logprintf(STDERR_FILENO,
"SWTPM_NVRAM_StoreData: Error (fatal) opening %s for "
"write failed, %s\n", tmpfile, strerror(errno));
"SWTPM_NVRAM_StoreData_Dir: Error (fatal), data write of %u bytes failed: %s\n",
filedata_length, strerror(errno));
rc = TPM_FAIL;
}
}
/* write the data to the file */
if (rc == 0) {
TPM_DEBUG(" SWTPM_NVRAM_StoreData: Writing %u bytes of data\n",
filedata_length);
lrc = write_full(fd, filedata, filedata_length);
if (lrc != filedata_length) {
logprintf(STDERR_FILENO,
"SWTPM_NVRAM_StoreData: Error (fatal), data write "
"of %u only wrote %u\n", filedata_length, lrc);
rc = TPM_FAIL;
}
}
if (fd >= 0) {
TPM_DEBUG(" SWTPM_NVRAM_StoreData: Closing file %s\n", tmpfile);
irc = close(fd); /* @1 */
if (irc != 0) {
logprintf(STDERR_FILENO,
"SWTPM_NVRAM_StoreData: Error (fatal) closing file\n");
rc = TPM_FAIL;
}
else {
TPM_DEBUG(" SWTPM_NVRAM_StoreData: Closed file %s\n", tmpfile);
}
}
if (rc == 0 && fd >= 0) {
irc = rename(tmpfile, filepath);
if (irc != 0) {
logprintf(STDERR_FILENO,
"SWTPM_NVRAM_StoreData: Error (fatal) renaming file: %s\n",
"SWTPM_NVRAM_StoreData_Dir: Error (fatal) renaming file: %s\n",
strerror(errno));
rc = TPM_FAIL;
} else {
TPM_DEBUG(" SWTPM_NVRAM_StoreData: Renamed file to %s\n", filepath);
}
}
if (rc != 0 && fd >= 0) {
unlink(tmpfile);
}
return rc;
}

View File

@ -45,6 +45,7 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/stat.h>
#if defined __APPLE__
#include <fcntl.h>
@ -333,6 +334,49 @@ ssize_t writev_full(int fd, const struct iovec *iov, int iovcnt)
return n;
}
/*
* file_write: Write a buffer to a file.
*
* @filename: filename
* @flags: file open flags
* @mode: file mode bits
* @clear_umask: whether to clear the umask and restore it after
* @buffer: buffer
* @buflen: length of buffer
*
* Returns -1 in case an error occurred, number of bytes written otherwise.
*/
ssize_t file_write(const char *filename, int flags, mode_t mode,
bool clear_umask, const void *buffer, size_t buflen)
{
mode_t orig_umask = 0;
ssize_t res;
int fd;
if (clear_umask)
orig_umask = umask(0);
fd = open(filename, flags, mode);
if (clear_umask)
umask(orig_umask);
if (fd < 0)
return -1;
res = buflen;
if (write_full(fd, buffer, buflen) != res)
res = -1;
if (close(fd) < 0)
res = -1;
if (res < 0)
unlink(filename);
return res;
}
/*
* read_einter: Read bytes from a file descriptor into a buffer
* and handle EINTR. Perform one read().

View File

@ -72,6 +72,8 @@ char *fd_to_filename(int fd);
ssize_t write_full(int fd, const void *buffer, size_t buflen);
ssize_t writev_full(int fd, const struct iovec *iov, int iovcnt);
ssize_t file_write(const char *filename, int flags, mode_t mode,
bool clear_umask, const void *buffer, size_t buflen);
ssize_t read_eintr(int fd, void *buffer, size_t buflen);