mirror of
https://codeberg.org/libreboot/lbmk.git
synced 2026-07-11 05:52:36 +02:00
util/nvmutil: tighter pledge and unveil
call it sooner. set new_state afterward. i had to uncouple nv from some functions for this, and i also added some extra checks especially at exit, about whether to touch nv (whether it is initialised) Signed-off-by: Leah Rowe <leah@libreboot.org>
This commit is contained in:
+68
-66
@@ -151,6 +151,10 @@ main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
struct commands *cmd;
|
struct commands *cmd;
|
||||||
struct xfile *f;
|
struct xfile *f;
|
||||||
|
int fd;
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
char *tmp_path = NULL;
|
||||||
|
|
||||||
unsigned long *i;
|
unsigned long *i;
|
||||||
|
|
||||||
@@ -161,33 +165,21 @@ main(int argc, char *argv[])
|
|||||||
err(EINVAL, "Unsupported char size");
|
err(EINVAL, "Unsupported char size");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
nv = new_xstate();
|
|
||||||
|
|
||||||
if (nv == NULL)
|
|
||||||
err(errno, NULL);
|
|
||||||
if (nv->f.buf == NULL)
|
|
||||||
err(EINVAL, "Work buffer not initialised");
|
|
||||||
|
|
||||||
nv->argv0 = argv[0];
|
|
||||||
if (argc < 3)
|
if (argc < 3)
|
||||||
usage();
|
usage();
|
||||||
|
|
||||||
f = &nv->f;
|
|
||||||
|
|
||||||
f->fname = argv[1];
|
|
||||||
|
|
||||||
#ifdef NVMUTIL_UNVEIL
|
#ifdef NVMUTIL_UNVEIL
|
||||||
/*
|
/*
|
||||||
* if global tmp is a different filesystem,
|
* if global tmp is a different filesystem,
|
||||||
* unveil would trap on final file rename
|
* unveil would trap on final file rename
|
||||||
* and we can't know the path in advance
|
* and we can't know the path in advance
|
||||||
*/
|
*/
|
||||||
f->tname = new_tmpfile(&f->tmp_fd, 1, NULL);
|
tmp_path = new_tmpfile(&fd, 1, NULL);
|
||||||
#else
|
#else
|
||||||
f->tname = new_tmpfile(&f->tmp_fd, 0, NULL);
|
tmp_path = new_tmpfile(&fd, 0, NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (f->tname == NULL)
|
if (tmp_path == NULL)
|
||||||
err(errno, "Can't create tmpfile");
|
err(errno, "Can't create tmpfile");
|
||||||
|
|
||||||
#ifdef NVMUTIL_PLEDGE
|
#ifdef NVMUTIL_PLEDGE
|
||||||
@@ -204,6 +196,26 @@ main(int argc, char *argv[])
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
nv = new_xstate();
|
||||||
|
|
||||||
|
if (nv == NULL)
|
||||||
|
err(errno, NULL);
|
||||||
|
if (nv->f.buf == NULL)
|
||||||
|
err(EINVAL, "Work buffer not initialised");
|
||||||
|
|
||||||
|
nv->argv0 = argv[0];
|
||||||
|
f = &nv->f;
|
||||||
|
|
||||||
|
f->fname = argv[1];
|
||||||
|
f->tname = tmp_path;
|
||||||
|
f->tmp_fd = fd;
|
||||||
|
|
||||||
|
if(fstat(fd, &st) < 0)
|
||||||
|
err(errno, "can't stat tmpfile");
|
||||||
|
|
||||||
|
f->tmp_dev = st.st_dev;
|
||||||
|
f->tmp_ino = st.st_ino;
|
||||||
|
|
||||||
sanitize_command_list();
|
sanitize_command_list();
|
||||||
|
|
||||||
set_cmd(argc, argv);
|
set_cmd(argc, argv);
|
||||||
@@ -214,11 +226,11 @@ main(int argc, char *argv[])
|
|||||||
|
|
||||||
#ifdef NVMUTIL_UNVEIL
|
#ifdef NVMUTIL_UNVEIL
|
||||||
if (cmd->flags == O_RDONLY) {
|
if (cmd->flags == O_RDONLY) {
|
||||||
if (unveil(fname, "r") == -1)
|
if (unveil(f->fname, "r") == -1)
|
||||||
err(errno, "%s: unveil r", fname);
|
err(errno, "%s: unveil r", f->fname);
|
||||||
} else {
|
} else {
|
||||||
if (unveil(fname, "rwc") == -1)
|
if (unveil(f->tname, "rwc") == -1)
|
||||||
err(errno, "%s: unveil rw", fname);
|
err(errno, "%s: unveil rw", f->tname);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unveil(tname, "rwc") == -1)
|
if (unveil(tname, "rwc") == -1)
|
||||||
@@ -513,19 +525,18 @@ open_gbe_file(void)
|
|||||||
err(EINVAL, "File size must be 8KB, 16KB or 128KB");
|
err(EINVAL, "File size must be 8KB, 16KB or 128KB");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lock_file(f->gbe_fd) == -1)
|
if (lock_file(f->gbe_fd, cmd->flags) == -1)
|
||||||
err(errno, "%s: can't lock", f->fname);
|
err(errno, "%s: can't lock", f->fname);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
lock_file(int fd)
|
lock_file(int fd, int flags)
|
||||||
{
|
{
|
||||||
struct flock fl;
|
struct flock fl;
|
||||||
struct commands *cmd = &nv->cmd[nv->i];
|
|
||||||
|
|
||||||
memset(&fl, 0, sizeof(fl));
|
memset(&fl, 0, sizeof(fl));
|
||||||
|
|
||||||
if (cmd->flags == O_RDONLY)
|
if ((flags & O_ACCMODE) == O_RDONLY)
|
||||||
fl.l_type = F_RDLCK;
|
fl.l_type = F_RDLCK;
|
||||||
else
|
else
|
||||||
fl.l_type = F_WRLCK;
|
fl.l_type = F_WRLCK;
|
||||||
@@ -2340,8 +2351,6 @@ usage(void)
|
|||||||
void
|
void
|
||||||
err(int nvm_errval, const char *msg, ...)
|
err(int nvm_errval, const char *msg, ...)
|
||||||
{
|
{
|
||||||
struct xfile *f = &nv->f;
|
|
||||||
|
|
||||||
va_list args;
|
va_list args;
|
||||||
|
|
||||||
if (errno == 0)
|
if (errno == 0)
|
||||||
@@ -2357,12 +2366,7 @@ err(int nvm_errval, const char *msg, ...)
|
|||||||
vfprintf(stderr, msg, args);
|
vfprintf(stderr, msg, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
|
|
||||||
fprintf(stderr, ": %s", strerror(errno));
|
fprintf(stderr, ": %s\n", strerror(errno));
|
||||||
|
|
||||||
fprintf(stderr, "\n");
|
|
||||||
|
|
||||||
if (f->tname != NULL)
|
|
||||||
free(f->tname);
|
|
||||||
|
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
@@ -2370,28 +2374,32 @@ err(int nvm_errval, const char *msg, ...)
|
|||||||
int
|
int
|
||||||
exit_cleanup(void)
|
exit_cleanup(void)
|
||||||
{
|
{
|
||||||
struct xfile *f = &nv->f;
|
struct xfile *f;
|
||||||
|
|
||||||
int close_err = 0;
|
int close_err = 0;
|
||||||
int saved_errno = errno;
|
int saved_errno = errno;
|
||||||
|
|
||||||
if (f->gbe_fd > -1) {
|
if (nv != NULL) {
|
||||||
if (x_i_close(f->gbe_fd) == -1)
|
f = &nv->f;
|
||||||
close_err = 1;
|
|
||||||
f->gbe_fd = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (f->tmp_fd > -1) {
|
if (f->gbe_fd > -1) {
|
||||||
if (x_i_close(f->tmp_fd) == -1)
|
if (x_i_close(f->gbe_fd) == -1)
|
||||||
close_err = 1;
|
close_err = 1;
|
||||||
}
|
f->gbe_fd = -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (f->tname != NULL) {
|
if (f->tmp_fd > -1) {
|
||||||
if (unlink(f->tname) == -1)
|
if (x_i_close(f->tmp_fd) == -1)
|
||||||
close_err = 1;
|
close_err = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
f->tmp_fd = -1;
|
if (f->tname != NULL) {
|
||||||
|
if (unlink(f->tname) == -1)
|
||||||
|
close_err = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
f->tmp_fd = -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (saved_errno)
|
if (saved_errno)
|
||||||
errno = saved_errno;
|
errno = saved_errno;
|
||||||
@@ -2445,8 +2453,6 @@ getnvmprogname(void)
|
|||||||
char *
|
char *
|
||||||
new_tmpfile(int *fd, int local, const char *path)
|
new_tmpfile(int *fd, int local, const char *path)
|
||||||
{
|
{
|
||||||
struct xfile *f = &nv->f;
|
|
||||||
|
|
||||||
unsigned long maxlen;
|
unsigned long maxlen;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
||||||
@@ -2563,7 +2569,20 @@ new_tmpfile(int *fd, int local, const char *path)
|
|||||||
if (x_i_fchmod(fd_tmp, 0600) == -1)
|
if (x_i_fchmod(fd_tmp, 0600) == -1)
|
||||||
goto err_new_tmpfile;
|
goto err_new_tmpfile;
|
||||||
|
|
||||||
if (lock_file(fd_tmp) == -1)
|
flags = fcntl(fd_tmp, F_GETFL);
|
||||||
|
|
||||||
|
if (flags == -1)
|
||||||
|
goto err_new_tmpfile;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* O_APPEND would permit offsets
|
||||||
|
* to be ignored, which breaks
|
||||||
|
* positional read/write
|
||||||
|
*/
|
||||||
|
if (flags & O_APPEND)
|
||||||
|
goto err_new_tmpfile;
|
||||||
|
|
||||||
|
if (lock_file(fd_tmp, flags) == -1)
|
||||||
goto err_new_tmpfile;
|
goto err_new_tmpfile;
|
||||||
|
|
||||||
if (fstat(fd_tmp, &st) == -1)
|
if (fstat(fd_tmp, &st) == -1)
|
||||||
@@ -2582,10 +2601,6 @@ new_tmpfile(int *fd, int local, const char *path)
|
|||||||
if (lseek(fd_tmp, 0, SEEK_CUR) == (off_t)-1)
|
if (lseek(fd_tmp, 0, SEEK_CUR) == (off_t)-1)
|
||||||
goto err_new_tmpfile;
|
goto err_new_tmpfile;
|
||||||
|
|
||||||
/* inode will be checked later on write */
|
|
||||||
f->tmp_dev = st.st_dev;
|
|
||||||
f->tmp_ino = st.st_ino;
|
|
||||||
|
|
||||||
/* tmpfile has >1 hardlinks */
|
/* tmpfile has >1 hardlinks */
|
||||||
if (st.st_nlink > 1)
|
if (st.st_nlink > 1)
|
||||||
goto err_new_tmpfile;
|
goto err_new_tmpfile;
|
||||||
@@ -2594,19 +2609,6 @@ new_tmpfile(int *fd, int local, const char *path)
|
|||||||
if (st.st_nlink == 0)
|
if (st.st_nlink == 0)
|
||||||
goto err_new_tmpfile;
|
goto err_new_tmpfile;
|
||||||
|
|
||||||
flags = fcntl(fd_tmp, F_GETFL);
|
|
||||||
|
|
||||||
if (flags == -1)
|
|
||||||
goto err_new_tmpfile;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* O_APPEND would permit offsets
|
|
||||||
* to be ignored, which breaks
|
|
||||||
* positional read/write
|
|
||||||
*/
|
|
||||||
if (flags & O_APPEND)
|
|
||||||
goto err_new_tmpfile;
|
|
||||||
|
|
||||||
*fd = fd_tmp;
|
*fd = fd_tmp;
|
||||||
|
|
||||||
return dest;
|
return dest;
|
||||||
|
|||||||
@@ -66,6 +66,10 @@
|
|||||||
#define EXIT_SUCCESS 0
|
#define EXIT_SUCCESS 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef O_ACCMODE
|
||||||
|
#define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR)
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef O_BINARY
|
#ifndef O_BINARY
|
||||||
#define O_BINARY 0
|
#define O_BINARY 0
|
||||||
#endif
|
#endif
|
||||||
@@ -311,7 +315,7 @@ int xstrxcmp(const char *a, const char *b, unsigned long maxlen);
|
|||||||
* Prep files for reading
|
* Prep files for reading
|
||||||
*/
|
*/
|
||||||
void open_gbe_file(void);
|
void open_gbe_file(void);
|
||||||
int lock_file(int fd);
|
int lock_file(int fd, int flags);
|
||||||
void xopen(int *fd, const char *path, int flags, struct stat *st);
|
void xopen(int *fd, const char *path, int flags, struct stat *st);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
Reference in New Issue
Block a user