diff options
| author | Leah Rowe <leah@libreboot.org> | 2026-03-20 04:02:51 +0000 |
|---|---|---|
| committer | Leah Rowe <leah@libreboot.org> | 2026-03-22 13:50:44 +0000 |
| commit | 6838db4647b600bf5b356429f54850bf801e7ba4 (patch) | |
| tree | cc98541897703d2949af27dc050cad8cba5061a0 /util/nvmutil/lib/state.c | |
| parent | f50ffd6bb13c04cb185fb6311f8875582bf18388 (diff) | |
WIP: hardened mktemp
i'm pretty much nearly there. still no dir support,
only files.
i won't keep amending now - will do more, then
squash later.
Signed-off-by: Leah Rowe <leah@libreboot.org>
Diffstat (limited to 'util/nvmutil/lib/state.c')
| -rw-r--r-- | util/nvmutil/lib/state.c | 155 |
1 files changed, 81 insertions, 74 deletions
diff --git a/util/nvmutil/lib/state.c b/util/nvmutil/lib/state.c index 02a3e51c..9869bb14 100644 --- a/util/nvmutil/lib/state.c +++ b/util/nvmutil/lib/state.c @@ -23,8 +23,11 @@ #include "../include/common.h" struct xstate * -xstatus(int argc, char *argv[]) +xstart(int argc, char *argv[]) { + static int first_run = 1; + static int pre_init = 0; + static struct xstate us = { /* DO NOT MESS THIS UP, OR THERE WILL BE DEMONS */ { @@ -86,92 +89,52 @@ xstatus(int argc, char *argv[]) }; - static int first_run = 1; - - if (!first_run) - return &us; + struct xstate *x = &us; - us.f.buf = us.f.real_buf; + if (!first_run) { + if (pre_init) + err_no_cleanup(ECANCELED, + "Outside access to state during init"); - first_run = 0; - us.argv0 = argv[0]; + first_run = 0; - if (argc > 1) - us.f.fname = argv[1]; + return &us; + } if (argc < 3) - usage(); - -/* https://man.openbsd.org/pledge.2 - https://man.openbsd.org/unveil.2 */ -#if defined(__OpenBSD__) && defined(OpenBSD) -#if (OpenBSD) >= 604 - if (pledge("stdio flock rpath wpath cpath unveil", NULL) == -1) - err(errno, "pledge plus unveil"); -#elif (OpenBSD) >= 509 - if (pledge("stdio flock rpath wpath cpath", NULL) == -1) - err(errno, "pledge"); -#endif -#endif + err_no_cleanup(EINVAL, "xstart: Too few arguments"); + if (argv == NULL) + err_no_cleanup(EINVAL, "xstart: NULL argv"); + + first_run = 0; + pre_init = 1; -#ifndef S_ISREG - err(ECANCELED, "Can't determine file types (S_ISREG undefined)"); -#endif + us.f.buf = us.f.real_buf; -#ifndef CHAR_BIT - err(ECANCELED, "Unknown char size"); -#else - if (CHAR_BIT != 8) - err(EINVAL, "Unsupported char size"); -#endif + us.argv0 = argv[0]; + us.f.fname = argv[1]; #if defined(__OpenBSD__) && defined(OpenBSD) && \ (OpenBSD) >= 604 /* can only use local tmp on openbsd, due to unveil */ us.f.tname = new_tmpfile(&us.f.tmp_fd, 1, NULL); #else - us.f.tname = new_tmpfile(&us.f.tmp_fd, 0, NULL); -#endif - if (us.f.tname == NULL) - err(errno, "Can't create tmpfile"); - if (*us.f.tname == '\0') - err(errno, "tmp dir is an empty string"); - -#if defined(__OpenBSD__) && defined(OpenBSD) && \ - OpenBSD >= 604 - if (unveil(us.f.tname, "rwc") == -1) - err(errno, "unveil rwc: %s", us.f.tname); + // TODO: new_tmplate (do for above too) + us.f.tname = new_tmpfile(&us.f.tmp_fd, 0, NULL); // TODO: NULL BAD! #endif - if (fstat(us.f.tmp_fd, &us.f.tmp_st) < 0) - err(errno, "%s: stat", us.f.tname); - - sanitize_command_list(); /* parse user command */ +// TODO: CHECK ACCESSES VIA xstatus() set_cmd(argc, argv); set_cmd_args(argc, argv); -#if defined(__OpenBSD__) && defined(OpenBSD) && \ - (OpenBSD) >= 604 - if ((us.cmd[i].flags & O_ACCMODE) == O_RDONLY) { - if (unveil(us.f.fname, "r") == -1) - err(errno, "%s: unveil r", us.f.fname); - } else { - if (unveil(us.f.fname, "rwc") == -1) - err(errno, "%s: unveil rw", us.f.fname); - } - - if (unveil(us.f.tname, "rwc") == -1) - err(errno, "%s: unveil rwc", us.f.tname); - - if (unveil(NULL, NULL) == -1) - err(errno, "unveil block (rw)"); - - if (pledge("stdio flock rpath wpath cpath", NULL) == -1) - err(errno, "pledge (kill unveil)"); -#endif + if (us.f.tname == NULL) + err_no_cleanup(errno, "x->f.tname null"); + if (*us.f.tname == '\0') + err_no_cleanup(errno, "x->f.tname empty"); - open_gbe_file(); + if (fstat(us.f.tmp_fd, &us.f.tmp_st) < 0) + err_no_cleanup(errno, "%s: stat", us.f.tname); memset(us.f.real_buf, 0, sizeof(us.f.real_buf)); memset(us.f.bufcmp, 0, sizeof(us.f.bufcmp)); @@ -179,16 +142,55 @@ xstatus(int argc, char *argv[]) /* for good measure */ memset(us.f.pad, 0, sizeof(us.f.pad)); - copy_gbe(); - read_checksums(); + pre_init = 0; return &us; } +struct xstate * +xstatus(void) +{ + struct xstate *x = xstart(0, NULL); + + if (x == NULL) + err_no_cleanup(EACCES, "NULL pointer to xstate"); + + sanitize_command_list(); + + return x; +} + +/* early init functions that + should not access state + WARNING: + does not do cleanup. only + call this during pre-init + */ +void +err_no_cleanup(int nvm_errval, const char *msg, ...) +{ + va_list args; + + if (errno == 0) + errno = nvm_errval; + if (!errno) + errno = ECANCELED; + + fprintf(stderr, "nvmutil: "); + + va_start(args, msg); + vfprintf(stderr, msg, args); + va_end(args); + + fprintf(stderr, ": %s\n", strerror(errno)); + + exit(EXIT_FAILURE); +} + void err(int nvm_errval, const char *msg, ...) { - struct xstate *x = xstatus(0, NULL); + struct xstate *x = xstatus(); va_list args; @@ -214,7 +216,7 @@ err(int nvm_errval, const char *msg, ...) const char * getnvmprogname(void) { - struct xstate *x = xstatus(0, NULL); + struct xstate *x = xstatus(); const char *p; static char fallback[] = "nvmutil"; @@ -239,7 +241,7 @@ getnvmprogname(void) int exit_cleanup(void) { - struct xstate *x = xstatus(0, NULL); + struct xstate *x = xstatus(); struct xfile *f; int close_err; @@ -252,14 +254,19 @@ exit_cleanup(void) f = &x->f; if (f->gbe_fd > -1) { - if (close_on_eintr(f->gbe_fd) == -1) + if (close_on_eintr(f->gbe_fd) == -1) { + f->gbe_fd = -1; close_err = 1; + } f->gbe_fd = -1; } if (f->tmp_fd > -1) { - if (close_on_eintr(f->tmp_fd) == -1) + if (close_on_eintr(f->tmp_fd) == -1) { + f->tmp_fd = -1; close_err = 1; + } + f->tmp_fd = -1; } if (f->tname != NULL) { |
