diff options
Diffstat (limited to 'util/libreboot-utils')
| -rw-r--r-- | util/libreboot-utils/include/common.h | 4 | ||||
| -rw-r--r-- | util/libreboot-utils/lib/command.c | 4 | ||||
| -rw-r--r-- | util/libreboot-utils/lib/file.c | 8 | ||||
| -rw-r--r-- | util/libreboot-utils/lib/num.c | 2 | ||||
| -rw-r--r-- | util/libreboot-utils/lib/state.c | 26 | ||||
| -rw-r--r-- | util/libreboot-utils/lib/string.c | 7 | ||||
| -rw-r--r-- | util/libreboot-utils/mkhtemp.c | 50 | ||||
| -rw-r--r-- | util/libreboot-utils/nvmutil.c | 14 |
8 files changed, 69 insertions, 46 deletions
diff --git a/util/libreboot-utils/include/common.h b/util/libreboot-utils/include/common.h index 196f2810..da086425 100644 --- a/util/libreboot-utils/include/common.h +++ b/util/libreboot-utils/include/common.h @@ -494,11 +494,13 @@ int try_err(int loop_err, int errval); */ void usage(void); -void err_no_cleanup(int nvm_errval, const char *msg, ...); +void err_no_cleanup(int stfu, int nvm_errval, const char *msg, ...); void b0rk(int nvm_errval, const char *msg, ...); int exit_cleanup(void); const char *getnvmprogname(void); +void err_mkhtemp(int stfu, int errval, const char *msg, ...); + /* libc hardening */ diff --git a/util/libreboot-utils/lib/command.c b/util/libreboot-utils/lib/command.c index 6d0e8856..c7048a23 100644 --- a/util/libreboot-utils/lib/command.c +++ b/util/libreboot-utils/lib/command.c @@ -110,7 +110,7 @@ set_cmd(int argc, char *argv[]) cmd = x->cmd[c].str; if (scmp(argv[2], cmd, MAX_CMD_LEN, &rval) < 0) - err_no_cleanup(EINVAL, + err_no_cleanup(0, EINVAL, "could not compare command strings"); if (rval != 0) continue; /* not the right command */ @@ -123,7 +123,7 @@ set_cmd(int argc, char *argv[]) return; } - err_no_cleanup(EINVAL, + err_no_cleanup(0, EINVAL, "Too few args on command '%s'", cmd); } diff --git a/util/libreboot-utils/lib/file.c b/util/libreboot-utils/lib/file.c index 46d5e016..552618d6 100644 --- a/util/libreboot-utils/lib/file.c +++ b/util/libreboot-utils/lib/file.c @@ -96,16 +96,16 @@ void xopen(int *fd_ptr, const char *path, int flags, struct stat *st) { if ((*fd_ptr = open(path, flags)) < 0) - err_no_cleanup(errno, "%s", path); + err_no_cleanup(0, errno, "%s", path); if (fstat(*fd_ptr, st) < 0) - err_no_cleanup(errno, "%s: stat", path); + err_no_cleanup(0, errno, "%s: stat", path); if (!S_ISREG(st->st_mode)) - err_no_cleanup(errno, "%s: not a regular file", path); + err_no_cleanup(0, errno, "%s: not a regular file", path); if (lseek_on_eintr(*fd_ptr, 0, SEEK_CUR, 1, 1) == (off_t)-1) - err_no_cleanup(errno, "%s: file not seekable", path); + err_no_cleanup(0, errno, "%s: file not seekable", path); } /* fsync() the directory of a file, diff --git a/util/libreboot-utils/lib/num.c b/util/libreboot-utils/lib/num.c index 43efba71..0b76e257 100644 --- a/util/libreboot-utils/lib/num.c +++ b/util/libreboot-utils/lib/num.c @@ -436,6 +436,6 @@ void check_bin(size_t a, const char *a_name) { if (a > 1) - err_no_cleanup(EINVAL, "%s must be 0 or 1, but is %lu", + err_no_cleanup(0, EINVAL, "%s must be 0 or 1, but is %lu", a_name, (size_t)a); } diff --git a/util/libreboot-utils/lib/state.c b/util/libreboot-utils/lib/state.c index 4ef7163f..42d060b7 100644 --- a/util/libreboot-utils/lib/state.c +++ b/util/libreboot-utils/lib/state.c @@ -98,9 +98,9 @@ xstart(int argc, char *argv[]) return &us; if (argc < 3) - err_no_cleanup(EINVAL, "xstart: Too few arguments"); + err_no_cleanup(0, EINVAL, "xstart: Too few arguments"); if (argv == NULL) - err_no_cleanup(EINVAL, "xstart: NULL argv"); + err_no_cleanup(0, EINVAL, "xstart: NULL argv"); first_run = 0; @@ -113,41 +113,41 @@ xstart(int argc, char *argv[]) us.f.tname = NULL; if ((realdir = realpath(us.f.fname, NULL)) == NULL) - err_no_cleanup(errno, "xstart: can't get realpath of %s", + err_no_cleanup(0, 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", + err_no_cleanup(0, errno, "xstart: don't know CWD of %s", us.f.fname); if ((us.f.base = strdup(base)) == NULL) - err_no_cleanup(errno, "strdup base"); + err_no_cleanup(0, 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); + err_no_cleanup(0, errno, "%s: open dir", dir); if (new_tmpfile(&us.f.tmp_fd, &us.f.tname, dir, ".gbe.XXXXXXXXXX") < 0) - err_no_cleanup(errno, "%s", us.f.tname); + err_no_cleanup(0, errno, "%s", us.f.tname); if (fs_dirname_basename(us.f.tname, &tmpdir, &tmpbase_local, 0) < 0) - err_no_cleanup(errno, "tmp basename"); + err_no_cleanup(0, errno, "tmp basename"); us.f.tmpbase = strdup(tmpbase_local); if (us.f.tmpbase == NULL) - err_no_cleanup(errno, "strdup tmpbase"); + err_no_cleanup(0, errno, "strdup tmpbase"); free_if_null(&tmpdir); if (us.f.tname == NULL) - err_no_cleanup(errno, "x->f.tname null"); + err_no_cleanup(0, errno, "x->f.tname null"); if (*us.f.tname == '\0') - err_no_cleanup(errno, "x->f.tname empty"); + err_no_cleanup(0, errno, "x->f.tname empty"); if (fstat(us.f.tmp_fd, &us.f.tmp_st) < 0) - err_no_cleanup(errno, "%s: stat", us.f.tname); + err_no_cleanup(0, 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)); @@ -164,7 +164,7 @@ xstatus(void) struct xstate *x = xstart(0, NULL); if (x == NULL) - err_no_cleanup(EACCES, "NULL pointer to xstate"); + err_no_cleanup(0, EACCES, "NULL pointer to xstate"); return x; } diff --git a/util/libreboot-utils/lib/string.c b/util/libreboot-utils/lib/string.c index 2f2be5f3..ea7ca30a 100644 --- a/util/libreboot-utils/lib/string.c +++ b/util/libreboot-utils/lib/string.c @@ -119,7 +119,7 @@ slen(const char *s, /* the one for nvmutil state is in state.c */ /* this one just exits */ void -err_no_cleanup(int nvm_errval, const char *msg, ...) +err_no_cleanup(int stfu, int nvm_errval, const char *msg, ...) { va_list args; int saved_errno = errno; @@ -141,7 +141,10 @@ err_no_cleanup(int nvm_errval, const char *msg, ...) vfprintf(stderr, msg, args); va_end(args); - fprintf(stderr, ": %s\n", strerror(errno)); + if (p != NULL) + fprintf(stderr, ": %s\n", strerror(errno)); + else + fprintf(stderr, "%s\n", strerror(errno)); exit(EXIT_FAILURE); } diff --git a/util/libreboot-utils/mkhtemp.c b/util/libreboot-utils/mkhtemp.c index 4408f763..e900c29b 100644 --- a/util/libreboot-utils/mkhtemp.c +++ b/util/libreboot-utils/mkhtemp.c @@ -10,6 +10,10 @@ * generally provides much higher strictness than previous * implementations such as mktemp, mkstemp or even mkdtemp. * + * It uses several modern features by default, e.g. openat2 + * and O_TMPFILE on Linux, with additional hardening; BSD + * projects only have openat so the code uses that there. + * * Many programs rely on mktemp, and they use TMPDIR in a way * that is quite insecure. Mkhtemp intends to change that, * quite dramatically, with: userspace sandbox (and use OS @@ -87,9 +91,10 @@ main(int argc, char *argv[]) int fd = -1; int type = MKHTEMP_FILE; + int stfu = 0; /* -q option */ if (lbgetprogname(argv[0]) == NULL) - err_no_cleanup(errno, "could not set progname"); + err_no_cleanup(stfu, errno, "could not set progname"); /* https://man.openbsd.org/pledge.2 */ #if defined(__OpenBSD__) && defined(OpenBSD) @@ -100,7 +105,7 @@ main(int argc, char *argv[]) #endif while ((c = - getopt(argc, argv, "dp:")) != -1) { + getopt(argc, argv, "qdp:")) != -1) { switch (c) { case 'd': @@ -111,6 +116,11 @@ main(int argc, char *argv[]) tmpdir = optarg; break; + case 'q': /* don't print errors */ + /* (exit status unchanged) */ + stfu = 1; + break; + default: goto err_usage; } @@ -119,20 +129,19 @@ main(int argc, char *argv[]) if (optind < argc) template = argv[optind]; if (optind + 1 < argc) - err_no_cleanup(EINVAL, - "usage: mkhtemp [-d] [-p dir] [template]\n"); + goto err_usage; /* custom template e.g. foo.XXXXXXXXXXXXXXXXXXXXX */ if (template != NULL) { if (slen(template, maxlen, &tlen) < 0) - err_no_cleanup(EINVAL, + err_no_cleanup(stfu, EINVAL, "invalid template"); for (p = template + tlen; p > template && *--p == 'X'; xc++); if (xc < 6) - err_no_cleanup(EINVAL, + err_no_cleanup(stfu, EINVAL, "template must end in at least 6 X"); } @@ -146,38 +155,35 @@ main(int argc, char *argv[]) if (tmpdir != NULL) { rp = realpath(tmpdir, resolved); if (rp == NULL) - err_no_cleanup(errno, - "%s", tmpdir); + err_no_cleanup(stfu, errno, "%s", tmpdir); tmpdir = resolved; } if (new_tmp_common(&fd, &s, type, tmpdir, template) < 0) - err_no_cleanup(errno, "%s", s); + err_no_cleanup(stfu, errno, "%s", s); #if defined(__OpenBSD__) && defined(OpenBSD) #if (OpenBSD) >= 509 if (pledge("stdio", NULL) == -1) - err_no_cleanup(errno, "pledge, exit"); + err_no_cleanup(stfu, errno, "pledge, exit"); #endif #endif if (s == NULL) - err_no_cleanup(EFAULT, "bad string initialisation"); - + err_no_cleanup(stfu, EFAULT, "bad string initialisation"); if (*s == '\0') - err_no_cleanup(EFAULT, "empty string initialisation"); - + err_no_cleanup(stfu, EFAULT, "empty string initialisation"); if (slen(s, maxlen, &len) < 0) - err_no_cleanup(EFAULT, "unterminated string initialisation"); + err_no_cleanup(stfu, EFAULT, "unterminated string initialisiert"); printf("%s\n", s); return EXIT_SUCCESS; err_usage: - err_no_cleanup(EINVAL, + err_no_cleanup(stfu, EINVAL, "usage: %s [-d] [-p dir] [template]\n", getnvmprogname()); }/* @@ -191,3 +197,15 @@ err_usage: */ + + + + + + + + + + + + diff --git a/util/libreboot-utils/nvmutil.c b/util/libreboot-utils/nvmutil.c index d9b91349..e02f60af 100644 --- a/util/libreboot-utils/nvmutil.c +++ b/util/libreboot-utils/nvmutil.c @@ -36,34 +36,34 @@ main(int argc, char *argv[]) size_t c; if (lbgetprogname(argv[0]) == NULL) - err_no_cleanup(errno, "could not set progname"); + err_no_cleanup(0, errno, "could not set progname"); /* 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_no_cleanup(errno, "pledge plus unveil, main"); + err_no_cleanup(0, errno, "pledge plus unveil, main"); if (unveil("/dev/null", "r") == -1) - err_no_cleanup(errno, "unveil r: /dev/null"); + err_no_cleanup(0, errno, "unveil r: /dev/null"); #elif (OpenBSD) >= 509 if (pledge("stdio flock rpath wpath cpath", NULL) == -1) - err_no_cleanup(errno, "pledge, main"); + err_no_cleanup(0, errno, "pledge, main"); #endif #endif #ifndef S_ISREG - err_no_cleanup(ECANCELED, + err_no_cleanup(0, ECANCELED, "Can't determine file types (S_ISREG undefined)"); #endif #if ((CHAR_BIT) != 8) - err_no_cleanup(ECANCELED, "Unsupported char size"); + err_no_cleanup(0, ECANCELED, "Unsupported char size"); #endif x = xstart(argc, argv); if (x == NULL) - err_no_cleanup(ECANCELED, "NULL state on init"); + err_no_cleanup(0, ECANCELED, "NULL state on init"); /* parse user command */ /* TODO: CHECK ACCESSES VIA xstatus() */ |
