diff options
| -rw-r--r-- | util/libreboot-utils/README.md | 4 | ||||
| -rw-r--r-- | util/libreboot-utils/include/common.h | 18 | ||||
| -rw-r--r-- | util/libreboot-utils/lib/file.c | 131 | ||||
| -rw-r--r-- | util/libreboot-utils/lib/io.c | 4 | ||||
| -rw-r--r-- | util/libreboot-utils/lib/mkhtemp.c | 85 | ||||
| -rw-r--r-- | util/libreboot-utils/lib/num.c | 21 | ||||
| -rw-r--r-- | util/libreboot-utils/lib/rand.c | 59 | ||||
| -rw-r--r-- | util/libreboot-utils/lib/state.c | 4 | ||||
| -rw-r--r-- | util/libreboot-utils/lib/string.c | 152 | ||||
| -rw-r--r-- | util/libreboot-utils/lottery.c | 12 | ||||
| -rw-r--r-- | util/libreboot-utils/mkhtemp.c | 3 | ||||
| -rw-r--r-- | util/libreboot-utils/nvmutil.c | 22 |
12 files changed, 321 insertions, 194 deletions
diff --git a/util/libreboot-utils/README.md b/util/libreboot-utils/README.md index 6e94035b..dca1b92e 100644 --- a/util/libreboot-utils/README.md +++ b/util/libreboot-utils/README.md @@ -31,7 +31,7 @@ of something like e.g. unveil, but in userspace! Mkhtemp is designed to be the most secure implementation possible, of mktemp, offering a heavy amount of hardening -over traditional mktemp. Written in C89, and the plan is +over traditional mktemp. Written in C99, and the plan is very much to keep this code portable over time - patches very much welcome. @@ -241,7 +241,7 @@ a drop-in replacement on Linux distros (and BSDs if they want it), while providing a more hardened version and recommending that where possible. -~~Rewrite it in rust~~ (nothing against it though, I just like C89 for some reason) +~~Rewrite it in rust~~ (nothing against it though, I just like C99 for some reason) Also, generally document the history of mktemp, and how mkhtemp works in comparison. diff --git a/util/libreboot-utils/include/common.h b/util/libreboot-utils/include/common.h index abd153be..da102f05 100644 --- a/util/libreboot-utils/include/common.h +++ b/util/libreboot-utils/include/common.h @@ -301,8 +301,6 @@ struct xstate { struct macaddr mac; struct xfile f; - char *argv0; - size_t i; /* index to cmd[] for current command */ int no_cmd; @@ -380,6 +378,7 @@ char *smalloc(char **buf, size_t size); void *vmalloc(void **buf, size_t size); int slen(const char *scmp, size_t maxlen, size_t *rval); +int vcmp(const void *s1, const void *s2, size_t n); int scmp(const char *a, const char *b, size_t maxlen, int *rval); int sdup(const char *s, @@ -396,10 +395,10 @@ int dcat(const char *s, size_t n, unsigned short hextonum(char ch_s); void spew_hex(const void *data, size_t len); -void *mkrbuf(size_t n); +void *rmalloc(size_t n); void rset(void *buf, size_t n); -void *mkrbuf(size_t n); -char *mkrstr(size_t n); +void *rmalloc(size_t n); +char *rchars(size_t n); size_t rsize(size_t n); /* Helper functions for command: dump @@ -484,6 +483,14 @@ ssize_t rw_over_nrw(ssize_t r, size_t nrw); off_t lseek_on_eintr(int fd, off_t off, int whence, int loop_eagain, int loop_eintr); int try_err(int loop_err, int errval); +ssize_t read_on_eintr(int fd, + void *buf, size_t count); +ssize_t write_on_eintr(int fd, + void *buf, size_t count); +ssize_t pread_on_eintr(int fd, + void *buf, size_t count, off_t off); +ssize_t pwrite_on_eintr(int fd, + void *buf, size_t count, off_t off); /* Error handling and cleanup */ @@ -524,7 +531,6 @@ mkhtemp_tmpfile_linux(int dirfd, int mkhtemp(int *fd, struct stat *st, char *template, int dirfd, const char *fname, struct stat *st_dir_initial, int type); -int mkhtemp_fill_random(char *p, size_t xc); int world_writeable_and_sticky(const char *s, int sticky_allowed, int always_sticky); int same_dir(const char *a, const char *b); diff --git a/util/libreboot-utils/lib/file.c b/util/libreboot-utils/lib/file.c index 3620f425..f35d9749 100644 --- a/util/libreboot-utils/lib/file.c +++ b/util/libreboot-utils/lib/file.c @@ -323,15 +323,15 @@ try_rw_again: real_pread_pwrite: #endif if (rw_type == IO_WRITE) - r = write(fd, mem, nrw); + r = write_on_eintr(fd, mem, nrw); else if (rw_type == IO_READ) - r = read(fd, mem, nrw); + r = read_on_eintr(fd, mem, nrw); #if defined(REAL_POS_IO) && \ REAL_POS_IO > 0 else if (rw_type == IO_PWRITE) - r = pwrite(fd, mem, nrw, off); + r = pwrite_on_eintr(fd, mem, nrw, off); else if (rw_type == IO_PREAD) - r = pread(fd, mem, nrw, off); + r = pread_on_eintr(fd, mem, nrw, off); #endif if (r == -1 && (errno == try_err(loop_eintr, EINTR) @@ -386,9 +386,9 @@ real_pread_pwrite: } if (rw_type == IO_PREAD) - r = read(fd, mem, nrw); + r = read_on_eintr(fd, mem, nrw); else if (rw_type == IO_PWRITE) - r = write(fd, mem, nrw); + r = write_on_eintr(fd, mem, nrw); if (rw_over_nrw(r, nrw) == -1) break; @@ -538,20 +538,6 @@ try_err(int loop_err, int errval) } void -free_and_set_null(char **buf) -{ - if (buf == NULL) - err_exit(EFAULT, - "null ptr (to ptr for freeing) in free_and_set_null"); - - if (*buf == NULL) - return; - - free(*buf); - *buf = NULL; -} - -void open_on_eintr(const char *path, int *fd, int flags, mode_t mode, struct stat *st) @@ -969,13 +955,118 @@ retry: return rval; } +ssize_t +read_on_eintr(int fd, + void *buf, size_t count) +{ + int saved_errno = errno; + int rval; + + if (if_err(buf == NULL, EFAULT) || + if_err(fd < 0, EBADF) || + if_err(count == 0, EINVAL)) + goto err; + +retry: + errno = 0; + + if ((rval = read(fd, buf, count)) == -1 && ( + errno == EINTR || + errno == EAGAIN || + errno == EWOULDBLOCK || + errno == ETXTBSY)) + goto retry; + + errno = saved_errno; + return rval; +err: + return set_errno(saved_errno, EIO); +} + +ssize_t +pread_on_eintr(int fd, + void *buf, size_t count, + off_t off) +{ + int saved_errno = errno; + int rval; + + if (if_err(buf == NULL, EFAULT) || + if_err(fd < 0, EBADF) || + if_err(off < 0, EFAULT) || + if_err(count == 0, EINVAL)) + goto err; + +retry: + errno = 0; + + if ((rval = pread(fd, buf, count, off)) == -1 && ( + errno == EINTR || + errno == EAGAIN || + errno == EWOULDBLOCK || + errno == ETXTBSY)) + goto retry; + + errno = saved_errno; + return rval; +err: + return set_errno(saved_errno, EIO); +} +ssize_t +write_on_eintr(int fd, + void *buf, size_t count) +{ + int saved_errno = errno; + int rval; + if (if_err(buf == NULL, EFAULT) || + if_err(fd < 0, EBADF) || + if_err(count == 0, EINVAL)) + goto err; +retry: + errno = 0; + if ((rval = write(fd, buf, count)) == -1 && ( + errno == EINTR || + errno == EAGAIN || + errno == EWOULDBLOCK || + errno == ETXTBSY)) + goto retry; + errno = saved_errno; + return rval; +err: + return set_errno(saved_errno, EIO); +} +ssize_t +pwrite_on_eintr(int fd, + void *buf, size_t count, + off_t off) +{ + int saved_errno = errno; + int rval; + if (if_err(buf == NULL, EFAULT) || + if_err(fd < 0, EBADF) || + if_err(off < 0, EFAULT) || + if_err(count == 0, EINVAL)) + goto err; +retry: + errno = 0; + if ((rval = pwrite(fd, buf, count, off)) == -1 && ( + errno == EINTR || + errno == EAGAIN || + errno == EWOULDBLOCK || + errno == ETXTBSY)) + goto retry; + errno = saved_errno; + return rval; +err: + return set_errno(saved_errno, EIO); +} diff --git a/util/libreboot-utils/lib/io.c b/util/libreboot-utils/lib/io.c index eac6073e..4938cdc8 100644 --- a/util/libreboot-utils/lib/io.c +++ b/util/libreboot-utils/lib/io.c @@ -143,7 +143,7 @@ read_file(void) if (_r < 0) err_exit(errno, "%s: read failed (cmp)", f->tname); - if (memcmp(f->buf, f->bufcmp, f->gbe_file_size) != 0) + if (vcmp(f->buf, f->bufcmp, f->gbe_file_size) != 0) err_exit(errno, "%s: %s: read contents differ (pre-test)", f->fname, f->tname); } @@ -329,7 +329,7 @@ check_written_part(size_t p) f->rw_check_err_read[p] = f->io_err_gbe = 1; else if ((size_t)rval != gbe_rw_size) f->rw_check_partial_read[p] = f->io_err_gbe = 1; - else if (memcmp(mem_offset, f->pad, gbe_rw_size) != 0) + else if (vcmp(mem_offset, f->pad, gbe_rw_size) != 0) f->rw_check_bad_part[p] = f->io_err_gbe = 1; if (f->rw_check_err_read[p] || diff --git a/util/libreboot-utils/lib/mkhtemp.c b/util/libreboot-utils/lib/mkhtemp.c index 61479b25..2ef26d67 100644 --- a/util/libreboot-utils/lib/mkhtemp.c +++ b/util/libreboot-utils/lib/mkhtemp.c @@ -135,19 +135,12 @@ new_tmp_common(int *fd, char **path, int type, if (slen(templatestr, maxlen, &templatestr_len) < 0) goto err; - /* sizeof adds an extra byte, useful - * because we also want '.' or '/' - */ + /* may as well calculate in advance */ destlen = dirlen + 1 + templatestr_len; - if (destlen > maxlen - 1) { - errno = EOVERFLOW; + /* full path: */ + if (scatn(3, (const char *[]) { tmpdir, "/", templatestr }, + maxlen, &dest) < 0) goto err; - } - - memcpy(smalloc(&dest, destlen + 1), tmpdir, dirlen); - *(dest + dirlen) = '/'; - memcpy(dest + dirlen + 1, templatestr, templatestr_len); - *(dest + destlen) = '\0'; fname = dest + dirlen + 1; @@ -533,7 +526,7 @@ mkhtemp(int *fd, struct stat *st_dir_initial, int type) { - size_t len = 0; + size_t template_len = 0; size_t xc = 0; size_t fname_len = 0; @@ -559,28 +552,28 @@ mkhtemp(int *fd, if_err(*fd >= 0, EEXIST) || if_err(dirfd < 0, EBADF) || - if_err_sys(slen(template, max_len, &len) < 0) || - if_err(len >= max_len, EMSGSIZE) + if_err_sys(slen(template, max_len, &template_len) < 0) || + if_err(template_len >= max_len, EMSGSIZE) || if_err_sys(slen(fname, max_len, &fname_len) < 0) || if_err(fname == NULL, EINVAL) || if_err(strrchr(fname, '/') != NULL, EINVAL)) return -1; - for (end = template + len; /* count X */ + for (end = template + template_len; /* count X */ end > template && *--end == 'X'; xc++); - if (if_err(xc < 3 || xc > len, EINVAL) || - if_err(fname_len > len, EOVERFLOW)) + if (if_err(xc < 3 || xc > template_len, EINVAL) || + if_err(fname_len > template_len, EOVERFLOW)) return -1; - if (if_err(memcmp(fname, template + len - fname_len, + if (if_err(vcmp(fname, template + template_len - fname_len, fname_len) != 0, EINVAL)) return -1; /* fname_copy = templatestr region only; p points to trailing XXXXXX */ memcpy(smalloc(&fname_copy, fname_len + 1), - template + len - fname_len, + template + template_len - fname_len, fname_len + 1); p = fname_copy + fname_len - xc; @@ -596,7 +589,7 @@ mkhtemp(int *fd, goto err; /* success: copy final name back */ - memcpy(template + len - fname_len, + memcpy(template + template_len - fname_len, fname_copy, fname_len); errno = saved_errno; @@ -627,6 +620,7 @@ mkhtemp_try_create(int dirfd, struct stat st_open; int saved_errno = errno; int rval = -1; + char *rstr = NULL; int file_created = 0; int dir_created = 0; @@ -636,8 +630,13 @@ mkhtemp_try_create(int dirfd, if_err(*fd >= 0, EEXIST)) goto err; - if (if_err_sys(mkhtemp_fill_random(p, xc) < 0) || - if_err_sys(fd_verify_dir_identity(dirfd, st_dir_initial) < 0)) + /* TODO: potential infinite loop under entropy failure. + * if attacker has control of rand - TODO: maybe add timeout + */ + memcpy(p, rstr = rchars(xc), xc); + free_and_set_null(&rstr); + + if (if_err_sys(fd_verify_dir_identity(dirfd, st_dir_initial) < 0)) goto err; if (type == MKHTEMP_FILE) { @@ -765,6 +764,7 @@ mkhtemp_tmpfile_linux(int dirfd, int tmpfd = -1; size_t retries; int linked = 0; + char *rstr = NULL; if (fd == NULL || st == NULL || fname_copy == NULL || p == NULL || @@ -785,8 +785,8 @@ mkhtemp_tmpfile_linux(int dirfd, for (retries = 0; retries < MKHTEMP_RETRY_MAX; retries++) { - if (mkhtemp_fill_random(p, xc) < 0) - goto err; + memcpy(p, rstr = rchars(xc), xc); + free_and_set_null(&rstr); if (fd_verify_dir_identity(dirfd, st_dir_initial) < 0) @@ -832,43 +832,6 @@ err: } #endif -/* TODO: potential infinite loop under entropy failure. - * e.g. keeps returning low quality RNG, or atacker - * has control (DoS attack potential). - * possible solution: add a timeout (and abort if - * the timeout is reached) - */ -int -mkhtemp_fill_random(char *p, size_t xc) -{ - static const char ch[] = - "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; - - unsigned char scratch[64]; - - size_t off = 0; - size_t i; - - /* clamp rand to prevent modulo bias */ - size_t limit = 256 - (256 % (sizeof(ch) - 1)); - - if (if_err(p == NULL, EFAULT)) - return -1; - -retry_rand: - rset(scratch, sizeof(scratch)); - - for (i = 0; i < sizeof(scratch) && off < xc; i++) { - if (scratch[i] < limit) - p[off++] = ch[scratch[i] % (sizeof(ch) - 1)]; - } - - if (off < xc) - goto retry_rand; - - return 0; -} - /* WARNING: **ONCE** per file. * * some of these checks will trip up diff --git a/util/libreboot-utils/lib/num.c b/util/libreboot-utils/lib/num.c index e4d0ce6b..e13a8853 100644 --- a/util/libreboot-utils/lib/num.c +++ b/util/libreboot-utils/lib/num.c @@ -50,6 +50,22 @@ hextonum(char ch_s) } /* basically hexdump -C */ +/* + TODO: optimise this + write a full util for hexdump + how to optimise: + don't call print tens of thousands of times! + convert the numbers manually, and cache everything + in a BUFSIZ sized buffer, with everything properly + aligned. i worked out that i could fit 79 rows + in a 8KB buffer (1264 bytes of numbers represented + as strings in hex) + this depends on the OS, and would be calculated at + runtime. + then: + don't use printf. just write it to stdout (basically + a simple cat implementation) +*/ void spew_hex(const void *data, size_t len) { @@ -64,7 +80,10 @@ spew_hex(const void *data, size_t len) for (i = 0; i < len; i += 16) { - printf("%08zx ", i); + if (len <= 4294967296) /* below 4GB */ + printf("%08zx ", i); + else + printf("%0*zx ", sizeof(size_t) * 2, i); for (j = 0; j < 16; j++) { diff --git a/util/libreboot-utils/lib/rand.c b/util/libreboot-utils/lib/rand.c index 9edc8a5b..9da8d9eb 100644 --- a/util/libreboot-utils/lib/rand.c +++ b/util/libreboot-utils/lib/rand.c @@ -72,6 +72,36 @@ * or your program dies. */ +/* random string generator, with + * rejection sampling. NOTE: only + * uses ASCII-safe characters, for + * printing on a unix terminal + * + * you still shouldn't use this for + * password generation; open diceware + * passphrases are better for that + * + * NOTE: the generated strings must + * ALSO be safe for file/directory names + * on unix-like os e.g. linux/bsd + */ +char * +rchars(size_t n) /* emulates spkmodem-decode */ +{ + static char ch[] = + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + + char *s = NULL; + size_t i; + + smalloc(&s, n + 1); + for (i = 0; i < n; i++) + s[i] = ch[rsize(sizeof(ch) - 1)]; + + *(s + n) = '\0'; + return s; +} + size_t rsize(size_t n) { @@ -85,32 +115,8 @@ rsize(size_t n) return rval % n; } -char * -mkrstr(size_t n) /* emulates spkmodem-decode */ -{ - char *s; - size_t i; - - if (n == 0) - err_exit(EPERM, "mkrbuf: zero-byte request"); - - if (n >= SIZE_MAX - 1) - err_exit(EOVERFLOW, "mkrbuf: overflow"); - - if (if_err((s = mkrbuf(n + 1)) == NULL, EFAULT)) - err_exit(EFAULT, "mkrstr: null"); - - for (i = 0; i < n; i++) - while(*(s + i) == '\0') - rset(s + i, 1); - - *(s + n) = '\0'; - - return s; -} - void * -mkrbuf(size_t n) +rmalloc(size_t n) { void *buf = NULL; rset(vmalloc(&buf, n), n); @@ -144,7 +150,8 @@ rset(void *buf, size_t n) int fd = -1; open_on_eintr("/dev/urandom", &fd, O_RDONLY, 0400, NULL); retry_rand: - if ((rc = read(fd, (unsigned char *)buf + off, n - off)) < 0) { + if ((rc = read_on_eintr(fd, + (unsigned char *)buf + off, n - off)) < 0) { #elif defined(__linux__) retry_rand: if ((rc = (ssize_t)syscall(SYS_getrandom, diff --git a/util/libreboot-utils/lib/state.c b/util/libreboot-utils/lib/state.c index a3cd5b1f..bcf2ccbc 100644 --- a/util/libreboot-utils/lib/state.c +++ b/util/libreboot-utils/lib/state.c @@ -77,9 +77,6 @@ xstart(int argc, char *argv[]) /* .f */ {0}, - /* .argv0 (for our getprogname implementation) */ - NULL, - /* ->i (index to cmd[]) */ 0, @@ -103,7 +100,6 @@ xstart(int argc, char *argv[]) us.f.buf = us.f.real_buf; - us.argv0 = argv[0]; us.f.fname = argv[1]; us.f.tmp_fd = -1; diff --git a/util/libreboot-utils/lib/string.c b/util/libreboot-utils/lib/string.c index d5e2de85..49c23663 100644 --- a/util/libreboot-utils/lib/string.c +++ b/util/libreboot-utils/lib/string.c @@ -19,6 +19,20 @@ #include "../include/common.h" +void +free_and_set_null(char **buf) +{ + if (buf == NULL) + err_exit(EFAULT, + "null ptr (to ptr for freeing) in free_and_set_null"); + + if (*buf == NULL) + return; + + free(*buf); + *buf = NULL; +} + /* safe(ish) malloc. use this and free_and_set_null() @@ -160,49 +174,46 @@ sdup(const char *s, } /* concatenate N number of strings */ -/* slen already checks null/termination */ int scatn(ssize_t sc, const char **sv, size_t max, char **rval) { - ssize_t i = 0; - - size_t ts = 0; - size_t *size = NULL; - - char *ct = NULL; int saved_errno = errno; - - if (if_err(sc <= 0, EINVAL) || - if_err(sc > SIZE_MAX / sizeof(size_t), EOVERFLOW) || - if_err(sv == NULL, EINVAL)) + char *final = NULL; + char *rcur = NULL; + char *rtmp = NULL; + size_t i; + + if (if_err(sc < 2, EINVAL) || + if_err(sv == NULL, EFAULT) || + if_err(rval == NULL || *rval != NULL, EFAULT)) goto err; - vmalloc((void **)&size, sizeof(size_t) * sc); + for (i = 0; i < sc; i++) { - for (i = 0; i < sc; i++, ts += size[i]) - if (if_err(sv[i] == NULL, EINVAL) || - slen(sv[i], max, &size[i]) < 0 || - if_err(size[i] > max - 1, EOVERFLOW) || - if_err((size[i] + ts) < ts, EOVERFLOW)) + if (if_err(sv[i] == NULL, EFAULT)) goto err; + else if (i == 0) { + if (sdup(sv[0], max, &final) < 0) + goto err; + continue; + } - if (if_err(ts > SIZE_MAX - 1, EOVERFLOW) || - if_err(ts > max - 1, EOVERFLOW)) - goto err; - - smalloc(&ct, ts + 1); - for (ts = i = 0; i < sc; i++, ts += size[i]) - memcpy(ct + ts, sv[i], size[i]); + rtmp = NULL; + if (scat(final, sv[i], max, &rtmp) < 0) + goto err; - *(ct + ts) = '\0'; - *rval = ct; + free_and_set_null(&final); + final = rtmp; + rtmp = NULL; + } - errno = saved_errno; + *rval = final; return 0; err: - free_and_set_null(&ct); - free_and_set_null((char **)&size); + free_and_set_null(&rcur); + free_and_set_null(&rtmp); + free_and_set_null(&final); return set_errno(saved_errno, EFAULT); } @@ -216,7 +227,7 @@ scat(const char *s1, const char *s2, size_t size2; char *rval = NULL; - if (dest == NULL || + if (if_err(dest == NULL || *dest != NULL, EFAULT) || slen(s1, n, &size1) < 0 || slen(s2, n, &size2) < 0 || if_err(size1 > SIZE_MAX - size2 - 1, EOVERFLOW)) { @@ -281,6 +292,39 @@ err: return -1; } +/* because no libc reimagination is complete + * without a reimplementation of memcmp. and + * no safe one is complete without null checks. + */ +int +vcmp(const void *s1, const void *s2, size_t n) +{ + size_t i = 0; + size_t a; + size_t b; + + if (if_err(s1 == NULL || s2 == NULL, EFAULT)) + err_exit(EFAULT, "vcmp: null input"); + + const unsigned char *x = s1; + const unsigned char *y = s2; + + for ( ; i + sizeof(size_t) <= n; i += sizeof(size_t)) { + + memcpy(&a, x + i, sizeof(size_t)); + memcpy(&b, y + i, sizeof(size_t)); + + if (a != b) + break; + } + + for ( ; i < n; i++) + if (x[i] != y[i]) + return (int)x[i] - (int)y[i]; + + return 0; +} + /* on functions that return with errno, * i sometimes have a default fallback, * which is set if errno wasn't changed, @@ -310,17 +354,13 @@ err_exit(int nvm_errval, const char *msg, ...) if (!errno) saved_errno = errno = ECANCELED; - if ((p = lbgetprogname()) != NULL) - fprintf(stderr, "%s: ", p); + fprintf(stderr, "%s: ", lbgetprogname()); va_start(args, msg); vfprintf(stderr, msg, args); va_end(args); - if (p != NULL) - fprintf(stderr, ": %s\n", strerror(errno)); - else - fprintf(stderr, "%s\n", strerror(errno)); + fprintf(stderr, ": %s\n", strerror(errno)); exit(EXIT_FAILURE); } @@ -359,22 +399,16 @@ no_op(void) const char * lbgetprogname(void) { - static char *rval = NULL; - static char *p; - static int setname = 0; - - if (!setname) { - if ((rval = lbsetprogname(NULL)) == NULL) - return NULL; - - p = strrchr(rval, '/'); - if (p) - rval = p + 1; - - setname = 1; - } - - return rval; + char *name = lbsetprogname(NULL); + char *p = NULL; + if (name) + p = strrchr(name, '/'); + if (p) + return p + 1; + else if (name) + return name; + else + return "libreboot-utils"; } /* singleton. if string not null, @@ -385,17 +419,13 @@ lbgetprogname(void) char * lbsetprogname(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) - return NULL; + static int set = 0; - memcpy(smalloc(&progname, len + 1), argv0, len + 1); - setname = 1; + if (!set) { + if (argv0 == NULL || sdup(argv0, 4096, &progname) < 0) + return "libreboot-utils"; + set = 1; } return progname; diff --git a/util/libreboot-utils/lottery.c b/util/libreboot-utils/lottery.c index 0b3719a4..1f8ff2e0 100644 --- a/util/libreboot-utils/lottery.c +++ b/util/libreboot-utils/lottery.c @@ -18,22 +18,22 @@ main(int argc, char **argv) { int same = 0; char *buf; + size_t size = 8589934592; (void) argc, (void) argv; (void) errhook(exit_cleanup); - if (lbsetprogname(argv[0]) == NULL) - err_exit(errno, "could not set progname"); + (void) lbsetprogname(argv[0]); /* https://man.openbsd.org/pledge.2 */ xpledgex("stdio", NULL); - buf = mkrbuf(BUFSIZ); - if (!memcmp(buf, buf + (BUFSIZ >> 1), BUFSIZ >> 1)) + buf = rmalloc(size); + if (!vcmp(buf, buf + (size >> 1), size >> 1)) same = 1; if (argc < 2) /* no spew */ - spew_hex(buf, BUFSIZ); - free(buf); + spew_hex(buf, size); + free_and_set_null(&buf); fprintf(stderr, "\n%s\n", same ? "You win!" : "You lose!"); return same ^ 1; diff --git a/util/libreboot-utils/mkhtemp.c b/util/libreboot-utils/mkhtemp.c index 04ce1993..de86a2bf 100644 --- a/util/libreboot-utils/mkhtemp.c +++ b/util/libreboot-utils/mkhtemp.c @@ -62,8 +62,7 @@ main(int argc, char *argv[]) int type = MKHTEMP_FILE; (void) errhook(exit_cleanup); - if (lbsetprogname(argv[0]) == NULL) - err_exit(errno, "could not set progname"); + (void) lbsetprogname(argv[0]); /* https://man.openbsd.org/pledge.2 */ xpledgex("stdio flock rpath wpath cpath", NULL); diff --git a/util/libreboot-utils/nvmutil.c b/util/libreboot-utils/nvmutil.c index 49d81a01..ec41371f 100644 --- a/util/libreboot-utils/nvmutil.c +++ b/util/libreboot-utils/nvmutil.c @@ -33,8 +33,7 @@ main(int argc, char *argv[]) size_t c; (void) errhook(exit_cleanup); - if (lbsetprogname(argv[0]) == NULL) - err_exit(errno, "could not set progname"); + (void) lbsetprogname(argv[0]); /* https://man.openbsd.org/pledge.2 */ /* https://man.openbsd.org/unveil.2 */ @@ -96,5 +95,22 @@ main(int argc, char *argv[]) static void exit_cleanup(void) { - return; + struct xstate *x; + struct xfile *f; + + x = xstatus(); + if (x == NULL) + return; + + f = &x->f; + + /* close fds if still open */ + close_on_eintr(&f->tmp_fd); + close_on_eintr(&f->gbe_fd); + + /* unlink tmpfile if it exists */ + if (f->tname != NULL) { + (void) unlink(f->tname); + free_and_set_null(&f->tname); + } } |
