diff options
| author | Leah Rowe <leah@libreboot.org> | 2026-03-24 19:13:59 +0000 |
|---|---|---|
| committer | Leah Rowe <leah@libreboot.org> | 2026-03-24 19:19:33 +0000 |
| commit | 3522a235878900d8371db31ee7a18056861a3419 (patch) | |
| tree | f1eff6c09159623dceb0665bc23070a84188e413 /util/libreboot-utils/lib | |
| parent | 217ad55beda2201626c29b1429a94115f51f2f68 (diff) | |
util/nvmutil: use renameat for atomic write
not rename(). use renameat()
this re-uses the logic added for mkhtemp.
this will later enable more stringent
integrity checks, though we already verify
the integrity of a file after writing it
back, and renameat is always tied to the
descriptor, so it's fine.
Signed-off-by: Leah Rowe <leah@libreboot.org>
Diffstat (limited to 'util/libreboot-utils/lib')
| -rw-r--r-- | util/libreboot-utils/lib/io.c | 26 | ||||
| -rw-r--r-- | util/libreboot-utils/lib/state.c | 24 |
2 files changed, 27 insertions, 23 deletions
diff --git a/util/libreboot-utils/lib/io.c b/util/libreboot-utils/lib/io.c index 4ca7d150..295e15c0 100644 --- a/util/libreboot-utils/lib/io.c +++ b/util/libreboot-utils/lib/io.c @@ -432,32 +432,12 @@ gbe_mv(void) saved_errno = errno; - /* TODO: remove this path-based rename, - use fd */ - rval = rename(f->tname, f->fname); - - if (rval > -1) { - - /* rename on same filesystem - */ + rval = fs_rename_at(f->dirfd, f->tmpbase, + f->dirfd, f->base); + if (rval > -1) tmp_gbe_bin_exists = 0; -/* - if (fsync(dest_fd) < 0) { - f->io_err_gbe_bin = 1; - rval = -1; - } -*/ - - goto ret_gbe_mv; - } - - if (errno != EXDEV) - goto ret_gbe_mv; - - err(errno, "BUG: cross-filesystem move (this shouldn't happen)"); - ret_gbe_mv: /* TODO: this whole section is bloat. diff --git a/util/libreboot-utils/lib/state.c b/util/libreboot-utils/lib/state.c index 2d2f6087..e3cb0890 100644 --- a/util/libreboot-utils/lib/state.c +++ b/util/libreboot-utils/lib/state.c @@ -29,6 +29,8 @@ xstart(int argc, char *argv[]) static char *dir = NULL; static char *base = NULL; char *realdir = NULL; + char *tmpdir = NULL; + char *tmpbase_local = NULL; static struct xstate us = { { @@ -118,9 +120,27 @@ xstart(int argc, char *argv[]) err_no_cleanup(errno, "xstart: don't know CWD of %s", us.f.fname); + if ((us.f.base = strdup(base)) == NULL) + err_no_cleanup(errno, "strdup base"); + + us.f.dirfd = fs_open(dir, + O_RDONLY | O_DIRECTORY); + if (us.f.dirfd < 0) + err_no_cleanup(errno, "%s: open dir", dir); + if (new_tmpfile(&us.f.tmp_fd, &us.f.tname, dir) < 0) err_no_cleanup(errno, "%s", us.f.tname); + if (fs_dirname_basename(us.f.tname, + &tmpdir, &tmpbase_local, 0) < 0) + err_no_cleanup(errno, "tmp basename"); + + us.f.tmpbase = strdup(tmpbase_local); + if (us.f.tmpbase == NULL) + err_no_cleanup(errno, "strdup tmpbase"); + + free_if_null(&tmpdir); + if (us.f.tname == NULL) err_no_cleanup(errno, "x->f.tname null"); if (*us.f.tname == '\0') @@ -197,6 +217,10 @@ exit_cleanup(void) if (f->tname != NULL) if (unlink(f->tname) == -1) close_err = 1; + + close_no_err(&f->dirfd); + free_if_null(&f->base); + free_if_null(&f->tmpbase); } if (saved_errno) |
