mirror of
https://github.com/stefanberger/swtpm.git
synced 2026-08-10 18:45:59 +00:00
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:
parent
7d2ee6ebc2
commit
9e2c3a1dec
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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().
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user