diff options
| -rw-r--r-- | util/libreboot-utils/include/common.h | 10 | ||||
| -rw-r--r-- | util/libreboot-utils/lib/file.c | 117 | ||||
| -rw-r--r-- | util/libreboot-utils/lib/mkhtemp.c | 33 | ||||
| -rw-r--r-- | util/libreboot-utils/lib/num.c | 21 | ||||
| -rw-r--r-- | util/libreboot-utils/lib/rand.c | 3 | ||||
| -rw-r--r-- | util/libreboot-utils/lib/state.c | 4 | ||||
| -rw-r--r-- | util/libreboot-utils/lib/string.c | 65 | ||||
| -rw-r--r-- | util/libreboot-utils/lottery.c | 10 | ||||
| -rw-r--r-- | util/libreboot-utils/mkhtemp.c | 3 | ||||
| -rw-r--r-- | util/libreboot-utils/nvmutil.c | 22 |
10 files changed, 208 insertions, 80 deletions
diff --git a/util/libreboot-utils/include/common.h b/util/libreboot-utils/include/common.h index 4b736808..0ccc02aa 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; @@ -484,6 +482,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 */ diff --git a/util/libreboot-utils/lib/file.c b/util/libreboot-utils/lib/file.c index 48eb37ed..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; @@ -955,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/mkhtemp.c b/util/libreboot-utils/lib/mkhtemp.c index 72942868..bba8a7ca 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(memcmp(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; 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 2aa0de3a..9da8d9eb 100644 --- a/util/libreboot-utils/lib/rand.c +++ b/util/libreboot-utils/lib/rand.c @@ -150,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 c3cf4519..39b31cb0 100644 --- a/util/libreboot-utils/lib/string.c +++ b/util/libreboot-utils/lib/string.c @@ -174,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); } @@ -230,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)) { @@ -324,17 +321,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); } diff --git a/util/libreboot-utils/lottery.c b/util/libreboot-utils/lottery.c index 48565c87..fd39c68c 100644 --- a/util/libreboot-utils/lottery.c +++ b/util/libreboot-utils/lottery.c @@ -18,21 +18,21 @@ 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 = rmalloc(BUFSIZ); - if (!memcmp(buf, buf + (BUFSIZ >> 1), BUFSIZ >> 1)) + buf = rmalloc(size); + if (!memcmp(buf, buf + (size >> 1), size >> 1)) same = 1; if (argc < 2) /* no spew */ - spew_hex(buf, BUFSIZ); + spew_hex(buf, size); free_and_set_null(&buf); fprintf(stderr, "\n%s\n", same ? "You win!" : "You lose!"); 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); + } } |
