diff options
Diffstat (limited to 'util/libreboot-utils/mkhtemp.c')
| -rw-r--r-- | util/libreboot-utils/mkhtemp.c | 84 |
1 files changed, 60 insertions, 24 deletions
diff --git a/util/libreboot-utils/mkhtemp.c b/util/libreboot-utils/mkhtemp.c index 4408f763..61260b49 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,20 +91,13 @@ 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"); - -/* https://man.openbsd.org/pledge.2 */ -#if defined(__OpenBSD__) && defined(OpenBSD) -#if (OpenBSD) >= 509 - if (pledge("stdio flock rpath wpath cpath", NULL) == -1) - goto err_usage; -#endif -#endif + err_mkhtemp(0, errno, "could not set progname"); while ((c = - getopt(argc, argv, "dp:")) != -1) { + getopt(argc, argv, "qdp:")) != -1) { switch (c) { case 'd': @@ -111,28 +108,40 @@ main(int argc, char *argv[]) tmpdir = optarg; break; + case 'q': /* don't print errors */ + /* (exit status unchanged) */ + stfu = 1; + break; + default: goto err_usage; } } +/* https://man.openbsd.org/pledge.2 */ +#if defined(__OpenBSD__) && defined(OpenBSD) +#if (OpenBSD) >= 509 + if (pledge("stdio flock rpath wpath cpath", NULL) == -1) + goto err_usage; +#endif +#endif + 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_mkhtemp(stfu, EINVAL, "invalid template"); for (p = template + tlen; p > template && *--p == 'X'; xc++); if (xc < 6) - err_no_cleanup(EINVAL, + err_mkhtemp(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_mkhtemp(stfu, errno, "%s", tmpdir); tmpdir = resolved; } if (new_tmp_common(&fd, &s, type, tmpdir, template) < 0) - err_no_cleanup(errno, "%s", s); + err_mkhtemp(stfu, errno, "%s", s); #if defined(__OpenBSD__) && defined(OpenBSD) #if (OpenBSD) >= 509 if (pledge("stdio", NULL) == -1) - err_no_cleanup(errno, "pledge, exit"); + err_mkhtemp(errno, "pledge, exit"); #endif #endif if (s == NULL) - err_no_cleanup(EFAULT, "bad string initialisation"); - + err_mkhtemp(stfu, EFAULT, "bad string initialisation"); if (*s == '\0') - err_no_cleanup(EFAULT, "empty string initialisation"); - + err_mkhtemp(stfu, EFAULT, "empty string initialisation"); if (slen(s, maxlen, &len) < 0) - err_no_cleanup(EFAULT, "unterminated string initialisation"); + err_mkhtemp(stfu, EFAULT, "unterminated string initialisiert"); printf("%s\n", s); return EXIT_SUCCESS; err_usage: - err_no_cleanup(EINVAL, + err_mkhtemp(stfu, EINVAL, "usage: %s [-d] [-p dir] [template]\n", getnvmprogname()); }/* @@ -191,3 +197,33 @@ err_usage: */ + +void +err_mkhtemp(int stfu, + int errval, const char *msg, ...) +{ + va_list args; + + if (stfu || msg == NULL) + goto out; + + va_start(args, msg); + vfprintf(stderr, msg, args); + va_end(args); + + err_no_cleanup(errval, msg, args); +out: + exit(EXIT_FAILURE); +} + + + + + + + + + + + + |
