mirror of
https://codeberg.org/libreboot/lbmk.git
synced 2026-03-25 13:29:03 +02:00
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 <leah@libreboot.org>
This commit is contained in:
@@ -497,6 +497,8 @@ const char *getnvmprogname(void);
|
|||||||
/* libc hardening
|
/* libc hardening
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
int new_tmpfile_at(int dirfd, struct stat *st_dir,
|
||||||
|
int *fd, char **name);
|
||||||
int new_tmpfile(int *fd, char **path);
|
int new_tmpfile(int *fd, char **path);
|
||||||
int new_tmpdir(int *fd, char **path);
|
int new_tmpdir(int *fd, char **path);
|
||||||
int new_tmp_common(int *fd, char **path, int type);
|
int new_tmp_common(int *fd, char **path, int type);
|
||||||
|
|||||||
@@ -413,7 +413,15 @@ gbe_mv(void)
|
|||||||
int tmp_gbe_bin_exists;
|
int tmp_gbe_bin_exists;
|
||||||
|
|
||||||
char *dest_tmp;
|
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
|
/* will be set 0 if it doesn't
|
||||||
*/
|
*/
|
||||||
@@ -424,6 +432,8 @@ gbe_mv(void)
|
|||||||
|
|
||||||
saved_errno = errno;
|
saved_errno = errno;
|
||||||
|
|
||||||
|
/* TODO: remove this path-based rename,
|
||||||
|
use fd */
|
||||||
rval = rename(f->tname, f->fname);
|
rval = rename(f->tname, f->fname);
|
||||||
|
|
||||||
if (rval > -1) {
|
if (rval > -1) {
|
||||||
@@ -433,10 +443,12 @@ gbe_mv(void)
|
|||||||
|
|
||||||
tmp_gbe_bin_exists = 0;
|
tmp_gbe_bin_exists = 0;
|
||||||
|
|
||||||
if (fsync_dir(f->fname) < 0) {
|
/*
|
||||||
|
if (fsync(dest_fd) < 0) {
|
||||||
f->io_err_gbe_bin = 1;
|
f->io_err_gbe_bin = 1;
|
||||||
rval = -1;
|
rval = -1;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
goto ret_gbe_mv;
|
goto ret_gbe_mv;
|
||||||
}
|
}
|
||||||
@@ -445,22 +457,28 @@ gbe_mv(void)
|
|||||||
goto ret_gbe_mv;
|
goto ret_gbe_mv;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* OR, cross-filesystem rename:
|
* cross-filesystem: copy into target dir tmp
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ((rval = f->tmp_fd = open(f->tname,
|
if (fs_dirname_basename(f->fname,
|
||||||
O_RDONLY | O_BINARY)) == -1)
|
&dir, &base, 0) < 0)
|
||||||
goto ret_gbe_mv;
|
goto ret_gbe_mv;
|
||||||
|
|
||||||
/* create replacement temp in target directory
|
dirfd = fs_open(dir,
|
||||||
*/
|
O_RDONLY | O_DIRECTORY);
|
||||||
if (new_tmpfile(&dest_fd, &f->fname) < 1)
|
|
||||||
goto ret_gbe_mv;
|
if (dirfd < 0)
|
||||||
if (dest_tmp == NULL)
|
|
||||||
goto ret_gbe_mv;
|
goto ret_gbe_mv;
|
||||||
|
|
||||||
/* copy data
|
if (fstat(dirfd, &st_dir) < 0)
|
||||||
*/
|
goto ret_gbe_mv;
|
||||||
|
|
||||||
|
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,
|
rval = rw_file_exact(f->tmp_fd, f->bufcmp,
|
||||||
f->gbe_file_size, 0, IO_PREAD,
|
f->gbe_file_size, 0, IO_PREAD,
|
||||||
NO_LOOP_EAGAIN, LOOP_EINTR,
|
NO_LOOP_EAGAIN, LOOP_EINTR,
|
||||||
@@ -486,7 +504,10 @@ gbe_mv(void)
|
|||||||
}
|
}
|
||||||
dest_fd = -1;
|
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;
|
goto ret_gbe_mv;
|
||||||
|
|
||||||
if (fsync_dir(f->fname) < 0) {
|
if (fsync_dir(f->fname) < 0) {
|
||||||
@@ -494,7 +515,10 @@ gbe_mv(void)
|
|||||||
goto ret_gbe_mv;
|
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:
|
ret_gbe_mv:
|
||||||
|
|
||||||
|
|||||||
@@ -39,6 +39,58 @@ new_tmpdir(int *fd, char **path)
|
|||||||
return new_tmp_common(fd, path, MKHTEMP_DIR);
|
return new_tmp_common(fd, path, MKHTEMP_DIR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* not used by mkhtemp util, but by nvmutil.
|
||||||
|
* it leaves an st variable set after return,
|
||||||
|
* so that verification can be done on a file
|
||||||
|
* being used, before writing it elsewhere
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
new_tmpfile_at(int dirfd, struct stat *st_dir,
|
||||||
|
int *fd, char **name)
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
char suffix[] = "tmp.XXXXXXXXXX";
|
||||||
|
size_t len;
|
||||||
|
char *buf = NULL;
|
||||||
|
char *fname;
|
||||||
|
int saved_errno = errno;
|
||||||
|
|
||||||
|
#if defined(PATH_LEN) && \
|
||||||
|
(PATH_LEN) >= 256
|
||||||
|
size_t maxlen = PATH_LEN;
|
||||||
|
#else
|
||||||
|
size_t maxlen = 4096;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (if_err(fd == NULL || name == NULL || st_dir == NULL, EFAULT) ||
|
||||||
|
if_err(*fd >= 0, EEXIST) ||
|
||||||
|
if_err(dirfd < 0, EBADF) ||
|
||||||
|
if_err_sys(slen(suffix, maxlen, &len) < 0) ||
|
||||||
|
if_err_sys((malloc(len + 1)) == NULL))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
memcpy(buf, suffix, len + 1);
|
||||||
|
fname = buf;
|
||||||
|
|
||||||
|
*fd = mkhtemp(fd, &st,
|
||||||
|
buf, dirfd, fname,
|
||||||
|
st_dir, MKHTEMP_FILE);
|
||||||
|
|
||||||
|
if (*fd < 0)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
*name = buf;
|
||||||
|
errno = saved_errno;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err:
|
||||||
|
free_if_null(&buf);
|
||||||
|
close_no_err(fd);
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* WARNING:
|
/* WARNING:
|
||||||
* on error, *path (at **path) may be
|
* on error, *path (at **path) may be
|
||||||
NULL, or if the error pertains to
|
NULL, or if the error pertains to
|
||||||
|
|||||||
Reference in New Issue
Block a user