From e9c5da1a25641e09244d3f52d7bb90983e0e5550 Mon Sep 17 00:00:00 2001 From: Leah Rowe Date: Tue, 24 Mar 2026 17:06:48 +0000 Subject: util/nvmutil: use new fs_open functions for gbe this unifies nvmutil's file handling with the handling used by mkhtemp. a special function has been written for this. this allows greater flexibility since we can more easily check the integrity of a file at inode/dev level; this complements nvmutil's existing content-based verification. (this also fixes nvmutil, so that gbe files can be changed again. mkhtemp broke it while i was writing it, but now everything works again) Signed-off-by: Leah Rowe --- util/libreboot-utils/lib/io.c | 50 ++++++++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 13 deletions(-) (limited to 'util/libreboot-utils/lib/io.c') diff --git a/util/libreboot-utils/lib/io.c b/util/libreboot-utils/lib/io.c index cc38e5c7..0bab9ee5 100644 --- a/util/libreboot-utils/lib/io.c +++ b/util/libreboot-utils/lib/io.c @@ -413,7 +413,15 @@ gbe_mv(void) int tmp_gbe_bin_exists; char *dest_tmp; - int dest_fd; + int dest_fd = -1; + + char *dir = NULL; + char *base = NULL; + char *dest_name = NULL; + + int dirfd = -1; + + struct stat st_dir; /* will be set 0 if it doesn't */ @@ -424,6 +432,8 @@ gbe_mv(void) saved_errno = errno; + /* TODO: remove this path-based rename, + use fd */ rval = rename(f->tname, f->fname); if (rval > -1) { @@ -433,10 +443,12 @@ gbe_mv(void) tmp_gbe_bin_exists = 0; - if (fsync_dir(f->fname) < 0) { +/* + if (fsync(dest_fd) < 0) { f->io_err_gbe_bin = 1; rval = -1; } +*/ goto ret_gbe_mv; } @@ -445,22 +457,28 @@ gbe_mv(void) goto ret_gbe_mv; /* - * OR, cross-filesystem rename: + * cross-filesystem: copy into target dir tmp */ - if ((rval = f->tmp_fd = open(f->tname, - O_RDONLY | O_BINARY)) == -1) + if (fs_dirname_basename(f->fname, + &dir, &base, 0) < 0) goto ret_gbe_mv; - /* create replacement temp in target directory - */ - if (new_tmpfile(&dest_fd, &f->fname) < 1) + dirfd = fs_open(dir, + O_RDONLY | O_DIRECTORY); + + if (dirfd < 0) goto ret_gbe_mv; - if (dest_tmp == NULL) + + if (fstat(dirfd, &st_dir) < 0) goto ret_gbe_mv; - /* copy data - */ + if (new_tmpfile_at(dirfd, &st_dir, + &dest_fd, &dest_name) < 0) + goto ret_gbe_mv; + + /* copy: tmp to local tmp */ + rval = rw_file_exact(f->tmp_fd, f->bufcmp, f->gbe_file_size, 0, IO_PREAD, NO_LOOP_EAGAIN, LOOP_EINTR, @@ -486,7 +504,10 @@ gbe_mv(void) } dest_fd = -1; - if (rename(dest_tmp, f->fname) == -1) + /* atomic replace */ + + if (fs_rename_at(dirfd, dest_name, + dirfd, base) == -1) goto ret_gbe_mv; if (fsync_dir(f->fname) < 0) { @@ -494,7 +515,10 @@ gbe_mv(void) goto ret_gbe_mv; } - free_if_null(&dest_tmp); + free_if_null(&dest_name); + free_if_null(&dir); + + tmp_gbe_bin_exists = 0; ret_gbe_mv: -- cgit v1.2.1