mirror of
https://codeberg.org/libreboot/lbmk.git
synced 2026-03-25 13:29:03 +02:00
Compare commits
5 Commits
9de01208b0
...
217ad55bed
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
217ad55bed | ||
|
|
c1befbcd3e | ||
|
|
6593e76c6a | ||
|
|
e9c5da1a25 | ||
|
|
56ab5a18fe |
@@ -497,9 +497,9 @@ const char *getnvmprogname(void);
|
|||||||
/* libc hardening
|
/* libc hardening
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int new_tmpfile(int *fd, char **path);
|
int new_tmpfile(int *fd, char **path, char *tmpdir);
|
||||||
int new_tmpdir(int *fd, char **path);
|
int new_tmpdir(int *fd, char **path, char *tmpdir);
|
||||||
int new_tmp_common(int *fd, char **path, int type);
|
int new_tmp_common(int *fd, char **path, int type, char *tmpdir);
|
||||||
int mkhtemp_try_create(int dirfd,
|
int mkhtemp_try_create(int dirfd,
|
||||||
struct stat *st_dir_initial,
|
struct stat *st_dir_initial,
|
||||||
char *fname_copy,
|
char *fname_copy,
|
||||||
@@ -517,7 +517,8 @@ int world_writeable_and_sticky(const char *s,
|
|||||||
int same_dir(const char *a, const char *b);
|
int same_dir(const char *a, const char *b);
|
||||||
int tmpdir_policy(const char *path,
|
int tmpdir_policy(const char *path,
|
||||||
int *allow_noworld_unsticky);
|
int *allow_noworld_unsticky);
|
||||||
char *env_tmpdir(int always_sticky, char **tmpdir);
|
char *env_tmpdir(int always_sticky, char **tmpdir,
|
||||||
|
char *override_tmpdir);
|
||||||
int secure_file(int *fd,
|
int secure_file(int *fd,
|
||||||
struct stat *st,
|
struct stat *st,
|
||||||
struct stat *expected,
|
struct stat *expected,
|
||||||
@@ -547,6 +548,7 @@ int mkdirat_on_eintr(int dirfd,
|
|||||||
const char *pathname, mode_t mode);
|
const char *pathname, mode_t mode);
|
||||||
int if_err(int condition, int errval);
|
int if_err(int condition, int errval);
|
||||||
int if_err_sys(int condition);
|
int if_err_sys(int condition);
|
||||||
|
char *lbgetprogname(char *argv0);
|
||||||
|
|
||||||
/* asserts */
|
/* asserts */
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
@@ -444,57 +456,7 @@ gbe_mv(void)
|
|||||||
if (errno != EXDEV)
|
if (errno != EXDEV)
|
||||||
goto ret_gbe_mv;
|
goto ret_gbe_mv;
|
||||||
|
|
||||||
/*
|
err(errno, "BUG: cross-filesystem move (this shouldn't happen)");
|
||||||
* OR, cross-filesystem rename:
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ((rval = f->tmp_fd = open(f->tname,
|
|
||||||
O_RDONLY | O_BINARY)) == -1)
|
|
||||||
goto ret_gbe_mv;
|
|
||||||
|
|
||||||
/* create replacement temp in target directory
|
|
||||||
*/
|
|
||||||
if (new_tmpfile(&dest_fd, &f->fname) < 1)
|
|
||||||
goto ret_gbe_mv;
|
|
||||||
if (dest_tmp == NULL)
|
|
||||||
goto ret_gbe_mv;
|
|
||||||
|
|
||||||
/* copy data
|
|
||||||
*/
|
|
||||||
rval = rw_file_exact(f->tmp_fd, f->bufcmp,
|
|
||||||
f->gbe_file_size, 0, IO_PREAD,
|
|
||||||
NO_LOOP_EAGAIN, LOOP_EINTR,
|
|
||||||
MAX_ZERO_RW_RETRY, OFF_ERR);
|
|
||||||
|
|
||||||
if (rval < 0)
|
|
||||||
goto ret_gbe_mv;
|
|
||||||
|
|
||||||
rval = rw_file_exact(dest_fd, f->bufcmp,
|
|
||||||
f->gbe_file_size, 0, IO_PWRITE,
|
|
||||||
NO_LOOP_EAGAIN, LOOP_EINTR,
|
|
||||||
MAX_ZERO_RW_RETRY, OFF_ERR);
|
|
||||||
|
|
||||||
if (rval < 0)
|
|
||||||
goto ret_gbe_mv;
|
|
||||||
|
|
||||||
if (fsync_on_eintr(dest_fd) == -1)
|
|
||||||
goto ret_gbe_mv;
|
|
||||||
|
|
||||||
if (close_on_eintr(dest_fd) == -1) {
|
|
||||||
dest_fd = -1;
|
|
||||||
goto ret_gbe_mv;
|
|
||||||
}
|
|
||||||
dest_fd = -1;
|
|
||||||
|
|
||||||
if (rename(dest_tmp, f->fname) == -1)
|
|
||||||
goto ret_gbe_mv;
|
|
||||||
|
|
||||||
if (fsync_dir(f->fname) < 0) {
|
|
||||||
f->io_err_gbe_bin = 1;
|
|
||||||
goto ret_gbe_mv;
|
|
||||||
}
|
|
||||||
|
|
||||||
free_if_null(&dest_tmp);
|
|
||||||
|
|
||||||
ret_gbe_mv:
|
ret_gbe_mv:
|
||||||
|
|
||||||
|
|||||||
@@ -27,18 +27,21 @@
|
|||||||
|
|
||||||
#include "../include/common.h"
|
#include "../include/common.h"
|
||||||
|
|
||||||
|
/* note: tmpdir is an override of TMPDIR or /tmp or /var/tmp */
|
||||||
int
|
int
|
||||||
new_tmpfile(int *fd, char **path)
|
new_tmpfile(int *fd, char **path, char *tmpdir)
|
||||||
{
|
{
|
||||||
return new_tmp_common(fd, path, MKHTEMP_FILE);
|
return new_tmp_common(fd, path, MKHTEMP_FILE, tmpdir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* note: tmpdir is an override of TMPDIR or /tmp or /var/tmp */
|
||||||
int
|
int
|
||||||
new_tmpdir(int *fd, char **path)
|
new_tmpdir(int *fd, char **path, char *tmpdir)
|
||||||
{
|
{
|
||||||
return new_tmp_common(fd, path, MKHTEMP_DIR);
|
return new_tmp_common(fd, path, MKHTEMP_DIR, tmpdir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* note: tmpdir is an override of TMPDIR or /tmp or /var/tmp */
|
||||||
/* 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
|
||||||
@@ -55,7 +58,8 @@ new_tmpdir(int *fd, char **path)
|
|||||||
* default to /tmp or /var/tmp
|
* default to /tmp or /var/tmp
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
new_tmp_common(int *fd, char **path, int type)
|
new_tmp_common(int *fd, char **path, int type,
|
||||||
|
char *tmpdir)
|
||||||
{
|
{
|
||||||
#if defined(PATH_LEN) && \
|
#if defined(PATH_LEN) && \
|
||||||
(PATH_LEN) >= 256
|
(PATH_LEN) >= 256
|
||||||
@@ -66,7 +70,6 @@ new_tmp_common(int *fd, char **path, int type)
|
|||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
||||||
char suffix[] = "tmp.XXXXXXXXXX";
|
char suffix[] = "tmp.XXXXXXXXXX";
|
||||||
char *tmpdir = NULL;
|
|
||||||
|
|
||||||
size_t dirlen;
|
size_t dirlen;
|
||||||
size_t destlen;
|
size_t destlen;
|
||||||
@@ -100,15 +103,25 @@ new_tmp_common(int *fd, char **path, int type)
|
|||||||
* (on error, it will not be touched)
|
* (on error, it will not be touched)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
*fd = -1;
|
*fd = -1;
|
||||||
|
|
||||||
|
if (tmpdir == NULL) { /* no user override */
|
||||||
|
#if defined(PERMIT_NON_STICKY_ALWAYS) && \
|
||||||
|
((PERMIT_NON_STICKY_ALWAYS) > 0)
|
||||||
|
tmpdir = env_tmpdir(PERMIT_NON_STICKY_ALWAYS, &fail_dir, NULL);
|
||||||
|
#else
|
||||||
|
tmpdir = env_tmpdir(0, &fail_dir, NULL);
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
|
||||||
#if defined(PERMIT_NON_STICKY_ALWAYS) && \
|
#if defined(PERMIT_NON_STICKY_ALWAYS) && \
|
||||||
((PERMIT_NON_STICKY_ALWAYS) > 0)
|
((PERMIT_NON_STICKY_ALWAYS) > 0)
|
||||||
tmpdir = env_tmpdir(PERMIT_NON_STICKY_ALWAYS, &fail_dir);
|
tmpdir = env_tmpdir(PERMIT_NON_STICKY_ALWAYS, &fail_dir,
|
||||||
|
tmpdir);
|
||||||
#else
|
#else
|
||||||
tmpdir = env_tmpdir(0, &fail_dir);
|
tmpdir = env_tmpdir(0, &fail_dir, tmpdir);
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
if (tmpdir == NULL)
|
if (tmpdir == NULL)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
@@ -189,7 +202,8 @@ err:
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
char *
|
char *
|
||||||
env_tmpdir(int bypass_all_sticky_checks, char **tmpdir)
|
env_tmpdir(int bypass_all_sticky_checks, char **tmpdir,
|
||||||
|
char *override_tmpdir)
|
||||||
{
|
{
|
||||||
char *t;
|
char *t;
|
||||||
int allow_noworld_unsticky;
|
int allow_noworld_unsticky;
|
||||||
@@ -198,7 +212,11 @@ env_tmpdir(int bypass_all_sticky_checks, char **tmpdir)
|
|||||||
char tmp[] = "/tmp";
|
char tmp[] = "/tmp";
|
||||||
char vartmp[] = "/var/tmp";
|
char vartmp[] = "/var/tmp";
|
||||||
|
|
||||||
t = getenv("TMPDIR");
|
/* tmpdir is a user override, if set */
|
||||||
|
if (override_tmpdir == NULL)
|
||||||
|
t = getenv("TMPDIR");
|
||||||
|
else
|
||||||
|
t = override_tmpdir;
|
||||||
|
|
||||||
if (t != NULL && *t != '\0') {
|
if (t != NULL && *t != '\0') {
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,9 @@ struct xstate *
|
|||||||
xstart(int argc, char *argv[])
|
xstart(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
static int first_run = 1;
|
static int first_run = 1;
|
||||||
|
static char *dir = NULL;
|
||||||
|
static char *base = NULL;
|
||||||
|
char *realdir = NULL;
|
||||||
|
|
||||||
static struct xstate us = {
|
static struct xstate us = {
|
||||||
{
|
{
|
||||||
@@ -107,7 +110,15 @@ xstart(int argc, char *argv[])
|
|||||||
us.f.tmp_fd = -1;
|
us.f.tmp_fd = -1;
|
||||||
us.f.tname = NULL;
|
us.f.tname = NULL;
|
||||||
|
|
||||||
if (new_tmpfile(&us.f.tmp_fd, &us.f.tname) < 0)
|
if ((realdir = realpath(us.f.fname, NULL)) == NULL)
|
||||||
|
err_no_cleanup(errno, "xstart: can't get realpath of %s",
|
||||||
|
us.f.fname);
|
||||||
|
|
||||||
|
if (fs_dirname_basename(realdir, &dir, &base, 0) < 0)
|
||||||
|
err_no_cleanup(errno, "xstart: don't know CWD of %s",
|
||||||
|
us.f.fname);
|
||||||
|
|
||||||
|
if (new_tmpfile(&us.f.tmp_fd, &us.f.tname, dir) < 0)
|
||||||
err_no_cleanup(errno, "%s", us.f.tname);
|
err_no_cleanup(errno, "%s", us.f.tname);
|
||||||
|
|
||||||
if (us.f.tname == NULL)
|
if (us.f.tname == NULL)
|
||||||
@@ -164,32 +175,6 @@ err(int nvm_errval, const char *msg, ...)
|
|||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
|
||||||
getnvmprogname(void)
|
|
||||||
{
|
|
||||||
struct xstate *x = xstatus();
|
|
||||||
|
|
||||||
const char *p;
|
|
||||||
static char fallback[] = "nvmutil";
|
|
||||||
|
|
||||||
char *rval = fallback;
|
|
||||||
|
|
||||||
if (x != NULL) {
|
|
||||||
|
|
||||||
if (x->argv0 != NULL && *x->argv0 != '\0')
|
|
||||||
rval = x->argv0;
|
|
||||||
else
|
|
||||||
return fallback;
|
|
||||||
}
|
|
||||||
|
|
||||||
p = strrchr(rval, '/');
|
|
||||||
|
|
||||||
if (p)
|
|
||||||
return p + 1;
|
|
||||||
else
|
|
||||||
return rval;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
exit_cleanup(void)
|
exit_cleanup(void)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -122,6 +122,8 @@ void
|
|||||||
err_no_cleanup(int nvm_errval, const char *msg, ...)
|
err_no_cleanup(int nvm_errval, const char *msg, ...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
|
int saved_errno = errno;
|
||||||
|
const char *p;
|
||||||
|
|
||||||
#if defined(__OpenBSD__) && defined(OpenBSD)
|
#if defined(__OpenBSD__) && defined(OpenBSD)
|
||||||
#if (OpenBSD) >= 509
|
#if (OpenBSD) >= 509
|
||||||
@@ -129,11 +131,11 @@ err_no_cleanup(int nvm_errval, const char *msg, ...)
|
|||||||
fprintf(stderr, "pledge failure during exit");
|
fprintf(stderr, "pledge failure during exit");
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!errno)
|
if (!errno)
|
||||||
errno = ECANCELED;
|
saved_errno = errno = ECANCELED;
|
||||||
|
|
||||||
fprintf(stderr, "nvmutil: ");
|
if ((p = getnvmprogname()) != NULL)
|
||||||
|
fprintf(stderr, "%s: ", p);
|
||||||
|
|
||||||
va_start(args, msg);
|
va_start(args, msg);
|
||||||
vfprintf(stderr, msg, args);
|
vfprintf(stderr, msg, args);
|
||||||
@@ -144,3 +146,61 @@ err_no_cleanup(int nvm_errval, const char *msg, ...)
|
|||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
getnvmprogname(void)
|
||||||
|
{
|
||||||
|
static char *rval = NULL;
|
||||||
|
static char *p;
|
||||||
|
static int setname = 0;
|
||||||
|
|
||||||
|
if (!setname) {
|
||||||
|
if ((rval = lbgetprogname(NULL)) == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
p = strrchr(rval, '/');
|
||||||
|
if (p)
|
||||||
|
rval = p + 1;
|
||||||
|
|
||||||
|
setname = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* singleton. if string not null,
|
||||||
|
sets the string. after set,
|
||||||
|
will not set anymore. either
|
||||||
|
way, returns the string
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
lbgetprogname(char *argv0)
|
||||||
|
{
|
||||||
|
static int setname = 0;
|
||||||
|
static char *progname = NULL;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
if (!setname) {
|
||||||
|
if (if_err(argv0 == NULL || *argv0 == '\0', EFAULT) ||
|
||||||
|
slen(argv0, 4096, &len) < 0 ||
|
||||||
|
(progname = malloc(len + 1)) == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
memcpy(progname, argv0, len + 1);
|
||||||
|
setname = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return progname;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -80,6 +80,9 @@ main(int argc, char *argv[])
|
|||||||
size_t maxlen = 4096;
|
size_t maxlen = 4096;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (lbgetprogname(argv[0]) == NULL)
|
||||||
|
err_no_cleanup(errno, "could not set progname");
|
||||||
|
|
||||||
/* https://man.openbsd.org/pledge.2 */
|
/* https://man.openbsd.org/pledge.2 */
|
||||||
#if defined(__OpenBSD__) && defined(OpenBSD)
|
#if defined(__OpenBSD__) && defined(OpenBSD)
|
||||||
#if (OpenBSD) >= 509
|
#if (OpenBSD) >= 509
|
||||||
@@ -103,7 +106,7 @@ main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (new_tmp_common(&fd, &s, type) < 0)
|
if (new_tmp_common(&fd, &s, type, NULL) < 0)
|
||||||
err_no_cleanup(errno, "%s", s);
|
err_no_cleanup(errno, "%s", s);
|
||||||
|
|
||||||
#if defined(__OpenBSD__) && defined(OpenBSD)
|
#if defined(__OpenBSD__) && defined(OpenBSD)
|
||||||
|
|||||||
@@ -35,6 +35,9 @@ main(int argc, char *argv[])
|
|||||||
|
|
||||||
size_t c;
|
size_t c;
|
||||||
|
|
||||||
|
if (lbgetprogname(argv[0]) == NULL)
|
||||||
|
err_no_cleanup(errno, "could not set progname");
|
||||||
|
|
||||||
/* https://man.openbsd.org/pledge.2
|
/* https://man.openbsd.org/pledge.2
|
||||||
https://man.openbsd.org/unveil.2 */
|
https://man.openbsd.org/unveil.2 */
|
||||||
#if defined(__OpenBSD__) && defined(OpenBSD)
|
#if defined(__OpenBSD__) && defined(OpenBSD)
|
||||||
|
|||||||
Reference in New Issue
Block a user