diff options
| -rw-r--r-- | util/libreboot-utils/include/common.h | 20 | ||||
| -rw-r--r-- | util/libreboot-utils/lib/checksum.c | 4 | ||||
| -rw-r--r-- | util/libreboot-utils/lib/command.c | 58 | ||||
| -rw-r--r-- | util/libreboot-utils/lib/file.c | 98 | ||||
| -rw-r--r-- | util/libreboot-utils/lib/io.c | 69 | ||||
| -rw-r--r-- | util/libreboot-utils/lib/mkhtemp.c | 42 | ||||
| -rw-r--r-- | util/libreboot-utils/lib/num.c | 42 | ||||
| -rw-r--r-- | util/libreboot-utils/lib/rand.c | 38 | ||||
| -rw-r--r-- | util/libreboot-utils/lib/state.c | 92 | ||||
| -rw-r--r-- | util/libreboot-utils/lib/string.c | 136 | ||||
| -rw-r--r-- | util/libreboot-utils/lib/usage.c | 2 | ||||
| -rw-r--r-- | util/libreboot-utils/lib/word.c | 2 | ||||
| -rw-r--r-- | util/libreboot-utils/lottery.c | 134 | ||||
| -rw-r--r-- | util/libreboot-utils/mkhtemp.c | 51 | ||||
| -rw-r--r-- | util/libreboot-utils/nvmutil.c | 101 |
15 files changed, 377 insertions, 512 deletions
diff --git a/util/libreboot-utils/include/common.h b/util/libreboot-utils/include/common.h index 77672846..d41c4a77 100644 --- a/util/libreboot-utils/include/common.h +++ b/util/libreboot-utils/include/common.h @@ -225,10 +225,12 @@ int fchmod(int fd, mode_t mode); /* command table */ +typedef void (*func_t)(void); + struct commands { size_t chk; char *str; - void (*run)(void); + func_t run; int argc; unsigned char arg_part; unsigned char chksum_read; @@ -375,6 +377,8 @@ void write_mac_part(size_t partnum); int xunveilx(const char *path, const char *permissions); int xpledgex(const char *promises, const char *execpromises); +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 scmp(const char *a, const char *b, @@ -393,7 +397,6 @@ int dcat(const char *s, size_t n, unsigned short hextonum(char ch_s); void *mkrbuf(size_t n); -void *rmalloc(size_t *size); /* don't ever use this */ void rset(void *buf, size_t n); void *mkrbuf(size_t n); char *mkrstr(size_t n); @@ -487,12 +490,11 @@ int try_err(int loop_err, int errval); */ void usage(void); -void err_no_cleanup(int stfu, int nvm_errval, const char *msg, ...); -void b0rk(int nvm_errval, const char *msg, ...); -int exit_cleanup(void); +void err_exit(int nvm_errval, const char *msg, ...); +func_t errhook(func_t ptr); /* hook function for cleanup on err */ const char *getnvmprogname(void); - -void err_mkhtemp(int stfu, int errval, const char *msg, ...); +void no_op(void); +void err_mkhtemp(int errval, const char *msg, ...); /* libc hardening */ @@ -537,14 +539,12 @@ int secure_file(int *fd, int check_seek, int do_lock, mode_t mode); -int close_on_eintr(int fd); +void close_on_eintr(int *fd); int fsync_on_eintr(int fd); int fs_rename_at(int olddirfd, const char *old, int newdirfd, const char *new); int fs_open(const char *path, int flags); -void close_no_err(int *fd); void free_and_set_null(char **buf); -int close_warn(int *fd, char *s); struct filesystem *rootfs(void); int fs_resolve_at(int dirfd, const char *path, int flags); int fs_next_component(const char **p, diff --git a/util/libreboot-utils/lib/checksum.c b/util/libreboot-utils/lib/checksum.c index 9a041989..97b0efca 100644 --- a/util/libreboot-utils/lib/checksum.c +++ b/util/libreboot-utils/lib/checksum.c @@ -59,10 +59,10 @@ read_checksums(void) if (_num_invalid >= _max_invalid) { if (_max_invalid == 1) - b0rk(ECANCELED, "%s: part %lu has a bad checksum", + err_exit(ECANCELED, "%s: part %lu has a bad checksum", f->fname, (size_t)f->part); - b0rk(ECANCELED, "%s: No valid checksum found in file", + err_exit(ECANCELED, "%s: No valid checksum found in file", f->fname); } } diff --git a/util/libreboot-utils/lib/command.c b/util/libreboot-utils/lib/command.c index c7048a23..d0f783dd 100644 --- a/util/libreboot-utils/lib/command.c +++ b/util/libreboot-utils/lib/command.c @@ -46,27 +46,27 @@ sanitize_command_index(size_t c) check_command_num(c); if (cmd->argc < 3) - b0rk(EINVAL, "cmd index %lu: argc below 3, %d", + err_exit(EINVAL, "cmd index %lu: argc below 3, %d", (size_t)c, cmd->argc); if (cmd->str == NULL) - b0rk(EINVAL, "cmd index %lu: NULL str", + err_exit(EINVAL, "cmd index %lu: NULL str", (size_t)c); if (*cmd->str == '\0') - b0rk(EINVAL, "cmd index %lu: empty str", + err_exit(EINVAL, "cmd index %lu: empty str", (size_t)c); if (slen(cmd->str, MAX_CMD_LEN +1, &rval) < 0) - b0rk(errno, "Could not get command length"); + err_exit(errno, "Could not get command length"); if (rval > MAX_CMD_LEN) { - b0rk(EINVAL, "cmd index %lu: str too long: %s", + err_exit(EINVAL, "cmd index %lu: str too long: %s", (size_t)c, cmd->str); } if (cmd->run == NULL) - b0rk(EINVAL, "cmd index %lu: cmd ptr null", + err_exit(EINVAL, "cmd index %lu: cmd ptr null", (size_t)c); check_bin(cmd->arg_part, "cmd.arg_part"); @@ -80,19 +80,19 @@ sanitize_command_index(size_t c) case NVM_SIZE: break; default: - b0rk(EINVAL, "Unsupported rw_size: %lu", + err_exit(EINVAL, "Unsupported rw_size: %lu", (size_t)gbe_rw_size); } if (gbe_rw_size > GBE_PART_SIZE) - b0rk(EINVAL, "rw_size larger than GbE part: %lu", + err_exit(EINVAL, "rw_size larger than GbE part: %lu", (size_t)gbe_rw_size); _flag = (cmd->flags & O_ACCMODE); if (_flag != O_RDONLY && _flag != O_RDWR) - b0rk(EINVAL, "invalid cmd.flags setting"); + err_exit(EINVAL, "invalid cmd.flags setting"); } void @@ -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(0, EINVAL, + err_exit(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(0, EINVAL, + err_exit(EINVAL, "Too few args on command '%s'", cmd); } @@ -148,11 +148,11 @@ set_cmd_args(int argc, char *argv[]) /* Maintainer bug */ if (cmd->arg_part && argc < 4) - b0rk(EINVAL, + err_exit(EINVAL, "arg_part set for command that needs argc4"); if (cmd->arg_part && i == CMD_SETMAC) - b0rk(EINVAL, + err_exit(EINVAL, "arg_part set on CMD_SETMAC"); if (i == CMD_SETMAC) { @@ -174,13 +174,13 @@ conv_argv_part_num(const char *part_str) unsigned char ch; if (part_str[0] == '\0' || part_str[1] != '\0') - b0rk(EINVAL, "Partnum string '%s' wrong length", part_str); + err_exit(EINVAL, "Partnum string '%s' wrong length", part_str); /* char signedness is implementation-defined */ ch = (unsigned char)part_str[0]; if (ch < '0' || ch > '1') - b0rk(EINVAL, "Bad part number (%c)", ch); + err_exit(EINVAL, "Bad part number (%c)", ch); return (size_t)(ch - '0'); } @@ -189,7 +189,7 @@ void check_command_num(size_t c) { if (!valid_command(c)) - b0rk(EINVAL, "Invalid run_cmd arg: %lu", + err_exit(EINVAL, "Invalid run_cmd arg: %lu", (size_t)c); } @@ -205,7 +205,7 @@ valid_command(size_t c) cmd = &x->cmd[c]; if (c != cmd->chk) - b0rk(EINVAL, + err_exit(EINVAL, "Invalid cmd chk value (%lu) vs arg: %lu", cmd->chk, c); @@ -240,10 +240,10 @@ parse_mac_string(void) size_t rval; if (slen(x->mac.str, 18, &rval) < 0) - b0rk(EINVAL, "Could not determine MAC length"); + err_exit(EINVAL, "Could not determine MAC length"); if (rval != 17) - b0rk(EINVAL, "MAC address is the wrong length"); + err_exit(EINVAL, "MAC address is the wrong length"); memset(mac->mac_buf, 0, sizeof(mac->mac_buf)); @@ -251,10 +251,10 @@ parse_mac_string(void) set_mac_byte(mac_byte); if ((mac->mac_buf[0] | mac->mac_buf[1] | mac->mac_buf[2]) == 0) - b0rk(EINVAL, "Must not specify all-zeroes MAC address"); + err_exit(EINVAL, "Must not specify all-zeroes MAC address"); if (mac->mac_buf[0] & 1) - b0rk(EINVAL, "Must not specify multicast MAC address"); + err_exit(EINVAL, "Must not specify multicast MAC address"); } void @@ -272,7 +272,7 @@ set_mac_byte(size_t mac_byte_pos) if (mac_str_pos < 15) { if ((separator = mac->str[mac_str_pos + 2]) != ':') - b0rk(EINVAL, "Invalid MAC address separator '%c'", + err_exit(EINVAL, "Invalid MAC address separator '%c'", separator); } @@ -294,9 +294,9 @@ set_mac_nib(size_t mac_str_pos, if ((hex_num = hextonum(mac_ch)) > 15) { if (hex_num >= 17) - b0rk(EIO, "Randomisation failure"); + err_exit(EIO, "Randomisation failure"); else - b0rk(EINVAL, "Invalid character '%c'", + err_exit(EINVAL, "Invalid character '%c'", mac->str[mac_str_pos + mac_nib_pos]); } @@ -509,7 +509,7 @@ cat(size_t nff) if ((size_t)x->cat != nff) { - b0rk(ECANCELED, "erroneous call to cat"); + err_exit(ECANCELED, "erroneous call to cat"); } fflush(NULL); @@ -532,12 +532,12 @@ void cat_buf(unsigned char *b) { if (b == NULL) - b0rk(errno, "null pointer in cat command"); + err_exit(errno, "null pointer in cat command"); if (rw_file_exact(STDOUT_FILENO, b, GBE_PART_SIZE, 0, IO_WRITE, LOOP_EAGAIN, LOOP_EINTR, MAX_ZERO_RW_RETRY, OFF_ERR) < 0) - b0rk(errno, "stdout: cat"); + err_exit(errno, "stdout: cat"); } void check_cmd(void (*fn)(void), @@ -547,7 +547,7 @@ check_cmd(void (*fn)(void), size_t i = x->i; if (x->cmd[i].run != fn) - b0rk(ECANCELED, "Running %s, but cmd %s is set", + err_exit(ECANCELED, "Running %s, but cmd %s is set", name, x->cmd[i].str); /* prevent second command @@ -559,6 +559,6 @@ check_cmd(void (*fn)(void), void cmd_helper_err(void) { - b0rk(ECANCELED, + err_exit(ECANCELED, "Erroneously running command twice"); } diff --git a/util/libreboot-utils/lib/file.c b/util/libreboot-utils/lib/file.c index 3ca50889..2b1adca8 100644 --- a/util/libreboot-utils/lib/file.c +++ b/util/libreboot-utils/lib/file.c @@ -73,16 +73,16 @@ void xopen(int *fd_ptr, const char *path, int flags, struct stat *st) { if ((*fd_ptr = open(path, flags)) < 0) - err_no_cleanup(0, errno, "%s", path); + err_exit(errno, "%s", path); if (fstat(*fd_ptr, st) < 0) - err_no_cleanup(0, errno, "%s: stat", path); + err_exit(errno, "%s: stat", path); if (!S_ISREG(st->st_mode)) - err_no_cleanup(0, errno, "%s: not a regular file", path); + err_exit(errno, "%s: not a regular file", path); if (lseek_on_eintr(*fd_ptr, 0, SEEK_CUR, 1, 1) == (off_t)-1) - err_no_cleanup(0, errno, "%s: file not seekable", path); + err_exit(errno, "%s: file not seekable", path); } int @@ -111,12 +111,11 @@ fsync_dir(const char *path) if (if_err(path == NULL, EFAULT) || if_err_sys(slen(path, maxlen, &pathlen) < 0) || if_err(pathlen >= maxlen || pathlen < 0, EMSGSIZE) || - if_err(pathlen == 0, EINVAL) - || - if_err_sys((dirbuf = malloc(pathlen + 1)) == NULL)) + if_err(pathlen == 0, EINVAL)) goto err_fsync_dir; - memcpy(dirbuf, path, pathlen + 1); + memcpy(smalloc(&dirbuf, pathlen + 1), + path, pathlen + 1); slash = strrchr(dirbuf, '/'); if (slash != NULL) { @@ -147,11 +146,7 @@ fsync_dir(const char *path) if_err_sys(fsync_on_eintr(dirfd) == -1)) goto err_fsync_dir; - if (close_on_eintr(dirfd) == -1) { - - dirfd = -1; - goto err_fsync_dir; - } + close_on_eintr(&dirfd); free_and_set_null(&dirbuf); @@ -164,7 +159,7 @@ err_fsync_dir: errno = EIO; free_and_set_null(&dirbuf); - close_no_err(&dirfd); + close_on_eintr(&dirfd); return -1; } @@ -590,66 +585,30 @@ free_and_set_null(char **buf) *buf = NULL; } -/* also returns error code */ -int -close_warn(int *fd, char *s) -{ - int saved_errno = errno; - - if (fd == NULL) { - if (s != NULL) - fprintf(stderr, "FAIL: %s: bad fd ptr\n", s); - return -1; - } - - if (*fd < 0 && s != NULL) { - fprintf(stderr, "WARN: %s: already closed\n", s); - } else if (close(*fd) < 0) { - if (s != NULL) - fprintf(stderr, "FAIL: %s: close\n", s); - return -1; - } - - *fd = -1; - errno = saved_errno; - - return 0; -} - -/* TODO: remove this, and just check - * err on every close. */ void -close_no_err(int *fd) +close_on_eintr(int *fd) { + int r; int saved_errno = errno; - if (fd == NULL || *fd < 0) - return; - - (void) close_on_eintr(*fd); - *fd = -1; - - errno = saved_errno; -} + if (fd == NULL) + err_exit(EINVAL, "close_on_eintr: null pointer"); -/* TODO: make fd a pointer insttead - and automatically reset -1 here */ -int -close_on_eintr(int fd) -{ - int r; - int saved_errno = errno; + if (*fd < 0) + return; do { - r = close(fd); + r = close(*fd); } while (r == -1 && ( errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK || errno == ETXTBSY)); - if (r >= 0) - errno = saved_errno; + if (r < 0) + err_exit(errno, "close_on_eintr: could not close"); - return r; + *fd = -1; + + errno = saved_errno; } int @@ -762,7 +721,7 @@ fs_resolve_at(int dirfd, const char *path, int flags) /* close previous fd if not the original input */ if (curfd != dirfd) - (void) close_on_eintr(curfd); + close_on_eintr(&curfd); curfd = nextfd; nextfd = -1; @@ -775,11 +734,11 @@ err: saved_errno = errno; if (nextfd >= 0) - (void) close_on_eintr(nextfd); + close_on_eintr(&nextfd); /* close curfd only if it's not the original */ if (curfd != dirfd && curfd >= 0) - (void) close_on_eintr(curfd); + close_on_eintr(&curfd); errno = saved_errno; return -1; @@ -848,7 +807,7 @@ fs_open_component(int dirfd, const char *name, if (!S_ISDIR(st.st_mode)) { - (void) close_on_eintr(fd); + close_on_eintr(&fd); errno = ENOTDIR; return -1; } @@ -862,7 +821,7 @@ fs_dirname_basename(const char *path, char **dir, char **base, int allow_relative) { - char *buf; + char *buf = NULL; char *slash; size_t len; int rval; @@ -874,11 +833,10 @@ fs_dirname_basename(const char *path, #endif if (path == NULL || dir == NULL || base == NULL || - if_err_sys(slen(path, maxlen, &len) < 0) || - if_err_sys((buf = malloc(len + 1)) == NULL)) + if_err_sys(slen(path, maxlen, &len) < 0)) return -1; - memcpy(buf, path, len + 1); + memcpy(smalloc(&buf, len + 1), path, len + 1); /* strip trailing slashes */ while (len > 1 && buf[len - 1] == '/') diff --git a/util/libreboot-utils/lib/io.c b/util/libreboot-utils/lib/io.c index 1f2064a0..f69954c8 100644 --- a/util/libreboot-utils/lib/io.c +++ b/util/libreboot-utils/lib/io.c @@ -32,16 +32,16 @@ open_gbe_file(void) O_NOFOLLOW | O_CLOEXEC | O_NOCTTY, &f->gbe_st); if (f->gbe_st.st_nlink > 1) - b0rk(EINVAL, + err_exit(EINVAL, "%s: warning: file has multiple (%lu) hard links\n", f->fname, (size_t)f->gbe_st.st_nlink); if (f->gbe_st.st_nlink == 0) - b0rk(EIO, "%s: file unlinked while open", f->fname); + err_exit(EIO, "%s: file unlinked while open", f->fname); _flags = fcntl(f->gbe_fd, F_GETFL); if (_flags == -1) - b0rk(errno, "%s: fcntl(F_GETFL)", f->fname); + err_exit(errno, "%s: fcntl(F_GETFL)", f->fname); /* O_APPEND allows POSIX write() to ignore * the current write offset and write at EOF, @@ -49,7 +49,7 @@ open_gbe_file(void) */ if (_flags & O_APPEND) - b0rk(EIO, "%s: O_APPEND flag", f->fname); + err_exit(EIO, "%s: O_APPEND flag", f->fname); f->gbe_file_size = f->gbe_st.st_size; @@ -59,11 +59,11 @@ open_gbe_file(void) case SIZE_128KB: break; default: - b0rk(EINVAL, "File size must be 8KB, 16KB or 128KB"); + err_exit(EINVAL, "File size must be 8KB, 16KB or 128KB"); } if (lock_file(f->gbe_fd, cmd->flags) == -1) - b0rk(errno, "%s: can't lock", f->fname); + err_exit(errno, "%s: can't lock", f->fname); } void @@ -98,7 +98,7 @@ read_file(void) MAX_ZERO_RW_RETRY, OFF_ERR); if (_r < 0) - b0rk(errno, "%s: read failed", f->fname); + err_exit(errno, "%s: read failed", f->fname); /* copy to tmpfile */ @@ -107,34 +107,34 @@ read_file(void) MAX_ZERO_RW_RETRY, OFF_ERR); if (_r < 0) - b0rk(errno, "%s: %s: copy failed", + err_exit(errno, "%s: %s: copy failed", f->fname, f->tname); /* file size comparison */ if (fstat(f->tmp_fd, &_st) == -1) - b0rk(errno, "%s: stat", f->tname); + err_exit(errno, "%s: stat", f->tname); f->gbe_tmp_size = _st.st_size; if (f->gbe_tmp_size != f->gbe_file_size) - b0rk(EIO, "%s: %s: not the same size", + err_exit(EIO, "%s: %s: not the same size", f->fname, f->tname); /* needs sync, for verification */ if (fsync_on_eintr(f->tmp_fd) == -1) - b0rk(errno, "%s: fsync (tmpfile copy)", f->tname); + err_exit(errno, "%s: fsync (tmpfile copy)", f->tname); _r = rw_file_exact(f->tmp_fd, f->bufcmp, f->gbe_file_size, 0, IO_PREAD, NO_LOOP_EAGAIN, LOOP_EINTR, MAX_ZERO_RW_RETRY, OFF_ERR); if (_r < 0) - b0rk(errno, "%s: read failed (cmp)", f->tname); + err_exit(errno, "%s: read failed (cmp)", f->tname); if (memcmp(f->buf, f->bufcmp, f->gbe_file_size) != 0) - b0rk(errno, "%s: %s: read contents differ (pre-test)", + err_exit(errno, "%s: %s: read contents differ (pre-test)", f->fname, f->tname); } @@ -152,10 +152,10 @@ write_gbe_file(void) return; if (same_file(f->tmp_fd, &f->tmp_st, 0) < 0) - b0rk(errno, "%s: file inode/device changed", f->tname); + err_exit(errno, "%s: file inode/device changed", f->tname); if (same_file(f->gbe_fd, &f->gbe_st, 1) < 0) - b0rk(errno, "%s: file has changed", f->fname); + err_exit(errno, "%s: file has changed", f->fname); update_checksum = cmd->chksum_write; @@ -188,7 +188,7 @@ rw_gbe_file_part(size_t p, int rw_type, gbe_rw_size = cmd->rw_size; if (rw_type < IO_PREAD || rw_type > IO_PWRITE) - b0rk(errno, "%s: %s: part %lu: invalid rw_type, %d", + err_exit(errno, "%s: %s: part %lu: invalid rw_type, %d", f->fname, rw_type_str, (size_t)p, rw_type); mem_offset = gbe_mem_offset(p, rw_type_str); @@ -198,11 +198,11 @@ rw_gbe_file_part(size_t p, int rw_type, gbe_rw_size, file_offset, rw_type); if (rval == -1) - b0rk(errno, "%s: %s: part %lu", + err_exit(errno, "%s: %s: part %lu", f->fname, rw_type_str, (size_t)p); if ((size_t)rval != gbe_rw_size) - b0rk(EIO, "%s: partial %s: part %lu", + err_exit(EIO, "%s: partial %s: part %lu", f->fname, rw_type_str, (size_t)p); } @@ -226,7 +226,7 @@ write_to_gbe_bin(void) */ if (fsync_on_eintr(f->tmp_fd) == -1) - b0rk(errno, "%s: fsync (pre-verification)", + err_exit(errno, "%s: fsync (pre-verification)", f->tname); check_written_part(0); @@ -235,12 +235,12 @@ write_to_gbe_bin(void) report_io_err_rw(); if (f->io_err_gbe) - b0rk(EIO, "%s: bad write", f->fname); + err_exit(EIO, "%s: bad write", f->fname); saved_errno = errno; - f->io_err_gbe_bin |= -close_warn(&f->tmp_fd, f->tname); - f->io_err_gbe_bin |= -close_warn(&f->gbe_fd, f->fname); + close_on_eintr(&f->tmp_fd); + close_on_eintr(&f->gbe_fd); errno = saved_errno; @@ -307,10 +307,10 @@ check_written_part(size_t p) memset(f->pad, 0xff, sizeof(f->pad)); if (same_file(f->tmp_fd, &f->tmp_st, 0) < 0) - b0rk(errno, "%s: file inode/device changed", f->tname); + err_exit(errno, "%s: file inode/device changed", f->tname); if (same_file(f->gbe_fd, &f->gbe_st, 1) < 0) - b0rk(errno, "%s: file changed during write", f->fname); + err_exit(errno, "%s: file changed during write", f->fname); rval = rw_gbe_file_exact(f->tmp_fd, f->pad, gbe_rw_size, file_offset, IO_PREAD); @@ -440,15 +440,8 @@ gbe_mv(void) ret_gbe_mv: - /* TODO: this whole section is bloat. - it can be generalised - */ - if (f->gbe_fd > -1) { - if (close_on_eintr(f->gbe_fd) < 0) { - f->gbe_fd = -1; - rval = -1; - } + close_on_eintr(&f->gbe_fd); f->gbe_fd = -1; if (fsync_dir(f->fname) < 0) { @@ -457,13 +450,7 @@ ret_gbe_mv: } } - if (f->tmp_fd > -1) { - if (close_on_eintr(f->tmp_fd) < 0) { - f->tmp_fd = -1; - rval = -1; - } - f->tmp_fd = -1; - } + close_on_eintr(&f->tmp_fd); /* before this function is called, * tmp_fd may have been moved @@ -540,11 +527,11 @@ gbe_x_offset(size_t p, const char *f_op, const char *d_type, off = ((off_t)p) * (off_t)nsize; if (off > ncmp - GBE_PART_SIZE) - b0rk(ECANCELED, "%s: GbE %s %s out of bounds", + err_exit(ECANCELED, "%s: GbE %s %s out of bounds", f->fname, d_type, f_op); if (off != 0 && off != ncmp >> 1) - b0rk(ECANCELED, "%s: GbE %s %s at bad offset", + err_exit(ECANCELED, "%s: GbE %s %s at bad offset", f->fname, d_type, f_op); return off; diff --git a/util/libreboot-utils/lib/mkhtemp.c b/util/libreboot-utils/lib/mkhtemp.c index c913ce6c..2726cb02 100644 --- a/util/libreboot-utils/lib/mkhtemp.c +++ b/util/libreboot-utils/lib/mkhtemp.c @@ -144,13 +144,7 @@ new_tmp_common(int *fd, char **path, int type, goto err; } - dest = malloc(destlen + 1); - if (dest == NULL) { - errno = ENOMEM; - goto err; - } - - memcpy(dest, tmpdir, dirlen); + memcpy(smalloc(&dest, destlen + 1), tmpdir, dirlen); *(dest + dirlen) = '/'; memcpy(dest + dirlen + 1, templatestr, templatestr_len); *(dest + destlen) = '\0'; @@ -170,7 +164,7 @@ new_tmp_common(int *fd, char **path, int type, if (*fd < 0) goto err; - close_no_err(&dirfd); + close_on_eintr(&dirfd); errno = saved_errno; *path = dest; @@ -186,8 +180,8 @@ err: free_and_set_null(&dest); - close_no_err(&dirfd); - close_no_err(fd); + close_on_eintr(&dirfd); + close_on_eintr(fd); /* where a TMPDIR isn't found, and we err, * we pass this back through for the @@ -354,8 +348,8 @@ same_dir(const char *a, const char *b) if (st_a.st_dev == st_b.st_dev && st_a.st_ino == st_b.st_ino) { - close_no_err(&fd_a); - close_no_err(&fd_b); + close_on_eintr(&fd_a); + close_on_eintr(&fd_b); success_same_dir: @@ -366,8 +360,8 @@ success_same_dir: return 1; } - close_no_err(&fd_a); - close_no_err(&fd_b); + close_on_eintr(&fd_a); + close_on_eintr(&fd_b); /* FAILURE (logical) */ @@ -380,8 +374,8 @@ err_same_dir: /* FAILURE (probably syscall) */ - close_no_err(&fd_a); - close_no_err(&fd_b); + close_on_eintr(&fd_a); + close_on_eintr(&fd_b); if (errno == saved_errno) errno = EIO; @@ -474,7 +468,7 @@ world_writeable_and_sticky( sticky_heaven: - close_no_err(&dirfd); + close_on_eintr(&dirfd); errno = saved_errno; return 1; @@ -484,8 +478,7 @@ sticky_hell: if (errno == saved_errno) errno = EPERM; - close_no_err(&dirfd); - errno = saved_errno; + close_on_eintr(&dirfd); return 0; } @@ -585,11 +578,8 @@ mkhtemp(int *fd, fname_len) != 0, EINVAL)) return -1; - if((fname_copy = malloc(fname_len + 1)) == NULL) - goto err; - /* fname_copy = templatestr region only; p points to trailing XXXXXX */ - memcpy(fname_copy, + memcpy(smalloc(&fname_copy, fname_len + 1), template + len - fname_len, fname_len + 1); p = fname_copy + fname_len - xc; @@ -616,7 +606,7 @@ mkhtemp(int *fd, errno = EEXIST; err: - close_no_err(fd); + close_on_eintr(fd); success: free_and_set_null(&fname_copy); @@ -742,7 +732,7 @@ mkhtemp_try_create(int dirfd, goto out; err: - close_no_err(fd); + close_on_eintr(fd); if (file_created) (void) unlinkat(dirfd, fname_copy, 0); @@ -837,7 +827,7 @@ err: if (linked) (void) unlinkat(dirfd, fname_copy, 0); - close_no_err(&tmpfd); + close_on_eintr(&tmpfd); return -1; } #endif diff --git a/util/libreboot-utils/lib/num.c b/util/libreboot-utils/lib/num.c index 79d6b409..66fc26f1 100644 --- a/util/libreboot-utils/lib/num.c +++ b/util/libreboot-utils/lib/num.c @@ -33,50 +33,24 @@ hextonum(char ch_s) ch = (unsigned char)ch_s; - if ((unsigned int)(ch - '0') <= 9) { - - rval = ch - '0'; - goto hextonum_success; - } + if ((unsigned int)(ch - '0') <= 9) + return ch - '0'; ch |= 0x20; - if ((unsigned int)(ch - 'a') <= 5) { - - rval = ch - 'a' + 10; - goto hextonum_success; - } - - if (ch == '?' || ch == 'x') { - - rset(&rval, sizeof(rval)); - - goto hextonum_success; - } - - goto err_hextonum; - -hextonum_success: - - errno = saved_errno; - return (unsigned short)rval & 0xf; - -err_hextonum: - - if (errno == saved_errno) - errno = EINVAL; - else - return 17; /* 17 indicates getrandom/urandom fail */ + if ((unsigned int)(ch - 'a') <= 5) + return ch - 'a' + 10; - return 16; /* invalid character */ + if (ch == '?' || ch == 'x') + return rsize(16); /* <-- with rejection sampling! */ - /* caller just checks >15. */ + return 16; } void check_bin(size_t a, const char *a_name) { if (a > 1) - err_no_cleanup(0, EINVAL, "%s must be 0 or 1, but is %lu", + err_exit(EINVAL, "%s must be 0 or 1, but is %lu", a_name, (size_t)a); } diff --git a/util/libreboot-utils/lib/rand.c b/util/libreboot-utils/lib/rand.c index 4c7458c7..99da713c 100644 --- a/util/libreboot-utils/lib/rand.c +++ b/util/libreboot-utils/lib/rand.c @@ -72,20 +72,14 @@ * or your program dies. */ -void * -rmalloc(size_t *rval) -{ - return if_err(rval == NULL, EFAULT) ? - NULL : mkrstr(*rval = rsize(BUFSIZ)); -} - size_t rsize(size_t n) { size_t rval = SIZE_MAX; if (!n) - err_no_cleanup(0, EFAULT, "rsize: division by zero"); + err_exit(EFAULT, "rsize: division by zero"); + /* rejection sampling (clamp rand to eliminate modulo bias) */ for (; rval >= SIZE_MAX - (SIZE_MAX % n); rset(&rval, sizeof(rval))); return rval % n; @@ -98,13 +92,13 @@ mkrstr(size_t n) /* emulates spkmodem-decode */ size_t i; if (n == 0) - err_no_cleanup(0, EPERM, "mkrbuf: zero-byte request"); + err_exit(EPERM, "mkrbuf: zero-byte request"); if (n >= SIZE_MAX - 1) - err_no_cleanup(0, EOVERFLOW, "mkrbuf: overflow"); + err_exit(EOVERFLOW, "mkrbuf: overflow"); if (if_err((s = mkrbuf(n + 1)) == NULL, EFAULT)) - err_no_cleanup(0, EFAULT, "mkrstr: null"); + err_exit(EFAULT, "mkrstr: null"); for (i = 0; i < n; i++) while(*(s + i) == '\0') @@ -118,18 +112,8 @@ mkrstr(size_t n) /* emulates spkmodem-decode */ void * mkrbuf(size_t n) { - void *buf = ""; - - if (n == 0) - err_no_cleanup(0, EPERM, "mkrbuf: zero-byte request"); - - if (n >= SIZE_MAX - 1) - err_no_cleanup(0, EOVERFLOW, "integer overflow in mkrbuf"); - - if ((buf = malloc(n)) == NULL) - err_no_cleanup(0, ENOMEM, "mkrbuf: malloc"); - - rset(buf, n); + void *buf = NULL; + rset(vmalloc(&buf, n), n); return buf; /* basically malloc() but with rand */ } @@ -142,7 +126,7 @@ rset(void *buf, size_t n) goto err; if (n == 0) - err_no_cleanup(0, EPERM, "rset: zero-byte request"); + err_exit(EPERM, "rset: zero-byte request"); #if (defined(__OpenBSD__) || defined(__FreeBSD__) || \ defined(__NetBSD__) || defined(__APPLE__) || \ @@ -185,7 +169,7 @@ retry_rand: #if defined(USE_URANDOM) && \ ((USE_URANDOM) > 0) - close_no_err(&fd); + close_on_eintr(&fd); #endif goto out; #endif @@ -195,9 +179,9 @@ out: err: #if defined(USE_URANDOM) && \ ((USE_URANDOM) > 0) - close_no_err(&fd); + close_on_eintr(&fd); #endif - err_no_cleanup(0, ECANCELED, + err_exit(ECANCELED, "Randomisation failure, possibly unsupported in your kernel"); exit(EXIT_FAILURE); } diff --git a/util/libreboot-utils/lib/state.c b/util/libreboot-utils/lib/state.c index 41c851fb..a3cd5b1f 100644 --- a/util/libreboot-utils/lib/state.c +++ b/util/libreboot-utils/lib/state.c @@ -4,9 +4,6 @@ * State machine (singleton) for nvmutil data. */ -#ifdef __OpenBSD__ -#include <sys/param.h> -#endif #include <sys/types.h> #include <sys/stat.h> @@ -98,9 +95,9 @@ xstart(int argc, char *argv[]) return &us; if (argc < 3) - err_no_cleanup(0, EINVAL, "xstart: Too few arguments"); + err_exit(EINVAL, "xstart: Too few arguments"); if (argv == NULL) - err_no_cleanup(0, EINVAL, "xstart: NULL argv"); + err_exit(EINVAL, "xstart: NULL argv"); first_run = 0; @@ -113,41 +110,41 @@ xstart(int argc, char *argv[]) us.f.tname = NULL; if ((realdir = realpath(us.f.fname, NULL)) == NULL) - err_no_cleanup(0, errno, "xstart: can't get realpath of %s", + err_exit(errno, "xstart: can't get realpath of %s", us.f.fname); if (fs_dirname_basename(realdir, &dir, &base, 0) < 0) - err_no_cleanup(0, errno, "xstart: don't know CWD of %s", + err_exit(errno, "xstart: don't know CWD of %s", us.f.fname); if ((us.f.base = strdup(base)) == NULL) - err_no_cleanup(0, errno, "strdup base"); + err_exit(errno, "strdup base"); us.f.dirfd = fs_open(dir, O_RDONLY | O_DIRECTORY); if (us.f.dirfd < 0) - err_no_cleanup(0, errno, "%s: open dir", dir); + err_exit(errno, "%s: open dir", dir); if (new_tmpfile(&us.f.tmp_fd, &us.f.tname, dir, ".gbe.XXXXXXXXXX") < 0) - err_no_cleanup(0, errno, "%s", us.f.tname); + err_exit(errno, "%s", us.f.tname); if (fs_dirname_basename(us.f.tname, &tmpdir, &tmpbase_local, 0) < 0) - err_no_cleanup(0, errno, "tmp basename"); + err_exit(errno, "tmp basename"); us.f.tmpbase = strdup(tmpbase_local); if (us.f.tmpbase == NULL) - err_no_cleanup(0, errno, "strdup tmpbase"); + err_exit(errno, "strdup tmpbase"); free_and_set_null(&tmpdir); if (us.f.tname == NULL) - err_no_cleanup(0, errno, "x->f.tname null"); + err_exit(errno, "x->f.tname null"); if (*us.f.tname == '\0') - err_no_cleanup(0, errno, "x->f.tname empty"); + err_exit(errno, "x->f.tname empty"); if (fstat(us.f.tmp_fd, &us.f.tmp_st) < 0) - err_no_cleanup(0, errno, "%s: stat", us.f.tname); + err_exit(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,70 +161,7 @@ xstatus(void) struct xstate *x = xstart(0, NULL); if (x == NULL) - err_no_cleanup(0, EACCES, "NULL pointer to xstate"); + err_exit(EACCES, "NULL pointer to xstate"); return x; } - -void -b0rk(int nvm_errval, const char *msg, ...) -{ - struct xstate *x = xstatus(); - - va_list args; - - if (errno == 0) - errno = nvm_errval; - if (!errno) - errno = ECANCELED; - - (void)exit_cleanup(); - - if (x != NULL) - fprintf(stderr, "%s: ", getnvmprogname()); - - va_start(args, msg); - vfprintf(stderr, msg, args); - va_end(args); - - fprintf(stderr, ": %s\n", strerror(errno)); - - exit(EXIT_FAILURE); -} - -int -exit_cleanup(void) -{ - struct xstate *x = xstatus(); - struct xfile *f; - - int close_err; - int saved_errno; - - close_err = 0; - saved_errno = errno; - - if (x != NULL) { - f = &x->f; - - close_no_err(&f->gbe_fd); - close_no_err(&f->tmp_fd); - close_no_err(&f->tmp_fd); - - if (f->tname != NULL) - if (unlink(f->tname) == -1) - close_err = 1; - - close_no_err(&f->dirfd); - free_and_set_null(&f->base); - free_and_set_null(&f->tmpbase); - } - - if (saved_errno) - errno = saved_errno; - - if (close_err) - return -1; - - return 0; -} diff --git a/util/libreboot-utils/lib/string.c b/util/libreboot-utils/lib/string.c index c6e09752..9e38a9e9 100644 --- a/util/libreboot-utils/lib/string.c +++ b/util/libreboot-utils/lib/string.c @@ -19,6 +19,51 @@ #include "../include/common.h" +/* safe(ish) malloc. + + use this and free_and_set_null() + in your program, to reduce the + chance of use after frees! + + if you use these functions in the + intended way, you will greatly reduce + the number of bugs in your code + */ +char * +smalloc(char **buf, size_t size) +{ + return (char *)vmalloc((void **)buf, size); +} +void * +vmalloc(void **buf, size_t size) +{ + void *rval = NULL; + + if (size >= SIZE_MAX - 1) + err_exit(EOVERFLOW, "integer overflow in vmalloc"); + if (buf == NULL) + err_exit(EFAULT, "Bad pointer passed to vmalloc"); + + /* lots of programs will + * re-initialise a buffer + * that was allocated, without + * freeing or NULLing it. this + * is here intentionally, to + * force the programmer to behave + */ + if (*buf != NULL) + err_exit(EFAULT, "Non-null pointer given to vmalloc"); + + if (!size) + err_exit(EFAULT, + "Tried to vmalloc(0) and that is very bad. Fix it now"); + + if ((rval = malloc(size)) == NULL) + err_exit(errno, "malloc fail in vmalloc"); + + return *buf = rval; +} + /* strict strcmp */ int scmp(const char *a, @@ -98,19 +143,16 @@ sdup(const char *s, size_t n, char **dest) { size_t size; - char *rval; + char *rval = NULL; if (dest == NULL || - slen(s, n, &size) < 0 || - if_err(size == SIZE_MAX, EOVERFLOW) || - (rval = malloc(size + 1)) == NULL) { - + slen(s, n, &size) < 0) { if (dest != NULL) *dest = NULL; return -1; } - memcpy(rval, s, size); + memcpy(smalloc(&rval, size + 1), s, size); *(rval + size) = '\0'; *dest = rval; @@ -133,10 +175,11 @@ scatn(ssize_t sc, const char **sv, if (if_err(sc <= 0, EINVAL) || if_err(sc > SIZE_MAX / sizeof(size_t), EOVERFLOW) || - if_err(sv == NULL, EINVAL) || - if_err((size = malloc(sizeof(size_t) * sc)) == NULL, ENOMEM)) + if_err(sv == NULL, EINVAL)) goto err; + vmalloc((void **)&size, sizeof(size_t) * sc); + for (i = 0; i < sc; i++, ts += size[i]) if (if_err(sv[i] == NULL, EINVAL) || slen(sv[i], max, &size[i]) < 0 || @@ -145,10 +188,10 @@ scatn(ssize_t sc, const char **sv, goto err; if (if_err(ts > SIZE_MAX - 1, EOVERFLOW) || - if_err(ts > max - 1, EOVERFLOW) || - if_err((ct = malloc(ts + 1)) == NULL, ENOMEM)) + 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]); @@ -175,20 +218,20 @@ scat(const char *s1, const char *s2, { size_t size1; size_t size2; - char *rval; + char *rval = NULL; if (dest == NULL || slen(s1, n, &size1) < 0 || slen(s2, n, &size2) < 0 || - if_err(size1 > SIZE_MAX - size2 - 1, EOVERFLOW) || - (rval = malloc(size1 + size2 + 1)) == NULL) { + if_err(size1 > SIZE_MAX - size2 - 1, EOVERFLOW)) { if (dest != NULL) *dest = NULL; return -1; } - memcpy(rval, s1, size1); + memcpy(smalloc(&rval, size1 + size2 + 1), + s1, size1); memcpy(rval + size1, s2, size2); *(rval + size1 + size2) = '\0'; @@ -210,17 +253,17 @@ dcat(const char *s, size_t n, if (dest1 == NULL || dest2 == NULL || slen(s, n, &size) < 0 || if_err(size == SIZE_MAX, EOVERFLOW) || - if_err(off >= size, EOVERFLOW) || - (rval1 = malloc(off + 1)) == NULL || - (rval2 = malloc(size - off + 1)) == NULL) { + if_err(off >= size, EOVERFLOW)) { goto err; } - memcpy(rval1, s, off); + memcpy(smalloc(&rval1, off + 1), + s, off); *(rval1 + off) = '\0'; - memcpy(rval2, s + off, size - off); + memcpy(smalloc(&rval2, size - off +1), + s + off, size - off); *(rval2 + size - off) = '\0'; *dest1 = rval1; @@ -245,18 +288,16 @@ err: /* the one for nvmutil state is in state.c */ /* this one just exits */ void -err_no_cleanup(int stfu, int nvm_errval, const char *msg, ...) +err_exit(int nvm_errval, const char *msg, ...) { va_list args; int saved_errno = errno; const char *p; -#if defined(__OpenBSD__) && defined(OpenBSD) -#if (OpenBSD) >= 509 - if (pledge("stdio", NULL) == -1) - fprintf(stderr, "pledge failure during exit"); -#endif -#endif + func_t err_cleanup = errhook(NULL); + err_cleanup(); + errno = saved_errno; + if (!errno) saved_errno = errno = ECANCELED; @@ -275,6 +316,37 @@ err_no_cleanup(int stfu, int nvm_errval, const char *msg, ...) exit(EXIT_FAILURE); } +/* the err function will + * call this upon exit, and + * cleanup will be performed + * e.g. you might want to + * close some files, depending + * on your program. + * see: err_exit() + */ +func_t errhook(func_t ptr) +{ + static int set = 0; + static func_t hook = NULL; + + if (!set) { + set = 1; + + if (ptr == NULL) + hook = no_op; + else + hook = ptr; + } + + return hook; +} + +void +no_op(void) +{ + return; +} + const char * getnvmprogname(void) { @@ -310,17 +382,18 @@ lbgetprogname(char *argv0) if (!setname) { if (if_err(argv0 == NULL || *argv0 == '\0', EFAULT) || - slen(argv0, 4096, &len) < 0 || - (progname = malloc(len + 1)) == NULL) + slen(argv0, 4096, &len) < 0) return NULL; - memcpy(progname, argv0, len + 1); + memcpy(smalloc(&progname, len + 1), argv0, len + 1); setname = 1; } return progname; } +/* https://man.openbsd.org/pledge.2 + https://man.openbsd.org/unveil.2 */ int xpledgex(const char *promises, const char *execpromises) { @@ -328,12 +401,11 @@ xpledgex(const char *promises, const char *execpromises) (void) promises, (void) execpromises, (void) saved_errno; #ifdef __OpenBSD__ if (pledge(promises, execpromises) == -1) - err_no_cleanup(0, errno, "pledge"); + err_exit(errno, "pledge"); #endif errno = saved_errno; return 0; } - int xunveilx(const char *path, const char *permissions) { @@ -341,7 +413,7 @@ xunveilx(const char *path, const char *permissions) (void) path, (void) permissions, (void) saved_errno; #ifdef __OpenBSD__ if (pledge(promises, execpromises) == -1) - err_no_cleanup(0, errno, "pledge"); + err_exit(errno, "pledge"); #endif errno = saved_errno; return 0; diff --git a/util/libreboot-utils/lib/usage.c b/util/libreboot-utils/lib/usage.c index 2b5a93ca..ebec119e 100644 --- a/util/libreboot-utils/lib/usage.c +++ b/util/libreboot-utils/lib/usage.c @@ -26,5 +26,5 @@ usage(void) util, util, util, util, util, util, util); - b0rk(EINVAL, "Too few arguments"); + err_exit(EINVAL, "Too few arguments"); } diff --git a/util/libreboot-utils/lib/word.c b/util/libreboot-utils/lib/word.c index 6563e67a..85e1d88b 100644 --- a/util/libreboot-utils/lib/word.c +++ b/util/libreboot-utils/lib/word.c @@ -63,6 +63,6 @@ check_nvm_bound(size_t c, size_t p) check_bin(p, "part number"); if (c >= NVM_WORDS) - b0rk(ECANCELED, "check_nvm_bound: out of bounds %lu", + err_exit(ECANCELED, "check_nvm_bound: out of bounds %lu", (size_t)c); } diff --git a/util/libreboot-utils/lottery.c b/util/libreboot-utils/lottery.c index f7c467e2..cbe8a871 100644 --- a/util/libreboot-utils/lottery.c +++ b/util/libreboot-utils/lottery.c @@ -1,76 +1,86 @@ /* SPDX-License-Identifier: MIT ( >:3 ) * Copyright (c) 2026 Leah Rowe <leah@libreboot.org> /| |\ - Presenting: a love song about non-determinism. / \ */ + Something something non-determinism / \ */ +#include <ctype.h> +#include <stddef.h> #include <stdio.h> #include <stdint.h> -#include <stdlib.h> /* (^.>) - are u lucky? */ -#include <string.h> /* \| /= */ -#include "include/common.h" /* l \ */ +#include <string.h> +#include <stdlib.h> +#include "include/common.h" -#define len_hell(x, y) ((((x) - (y)) < BUFSIZ) ? ((x) - (y)) : BUFSIZ) +static void +exit_cleanup(void); -static int rigged(void) +static void +spew_buf(const void *data, size_t len); + +int +main(int argc, char **argv) { - size_t size[5] = { 0, 0, 0, SIZE_MAX, SIZE_MAX}; - char *b1 = NULL, *b2 = NULL; - char *s = NULL; - size_t e = 0; - - int rval = 1; - -for (e = 0; e < SIZE_MAX; e++) { - if (rsize(e | 1) == 666) - goto heaven; - - size[3] = SIZE_MAX; - size[4] = SIZE_MAX; -hell: - if (!size[3]) { - if (!size[4]) - continue; - else --size[4]; - } else --size[3]; - - free_and_set_null(&b1); - free_and_set_null(&b2); - - size[0] = rsize(SIZE_MAX); /* \( ^o^)/ - then come play! */ - size[1] = rsize(SIZE_MAX); /* | | */ -/* / \ */ - if (!(size[0] && (size[0] == size[1]) && (size[0] <= SIZE_MAX)) || - ((size[0] & 1) && (*(b1 = mkrstr(1)) != *(b2 = mkrstr(1))))) - goto out; /* \(^-^)/ - it could be you! */ - if (!(size[0] &= ~(size_t)1)) /* \ / */ - goto hell; /* / \ */ - - if (s == NULL) { - if ((s = malloc(BUFSIZ)) == NULL) - goto out; - } + int same = 0; + char *buf; + + (void) argc, (void) argv; + xpledgex("stdio", NULL); + + (void) errhook(exit_cleanup); + + buf = mkrbuf(BUFSIZ + 1); + if (!memcmp(buf, buf + (BUFSIZ >> 1), BUFSIZ >> 1)) + same = 1; - for (size[1] = 0; size[1] < size[0]; size[1] += BUFSIZ) { - rset(s, size[2] = len_hell(size[0], size[1])); - if (!memcmp(s, s + (size[2] >> 1), size[2] >> 1)) - goto out; - } + if (argc < 2) /* no spew */ + spew_buf(buf, BUFSIZ); + free(buf); - goto hell; + fprintf(stderr, "\n%s\n", same ? "You win!" : "You lose!"); + return same ^ 1; } -heaven: - rval = 0; /* <-- WINNER!!! */ -out: - free_and_set_null(&b1); - free_and_set_null(&b2); - free_and_set_null(&s); - - return rval; + +static void +spew_buf(const void *data, size_t len) +{ + const unsigned char *buf = data; + unsigned char c; + size_t i, j; + + if (buf == NULL || + len == 0) + return; + + for (i = 0; i < len; i += 16) { + + printf("%08zx ", i); + + for (j = 0; j < 16; j++) { + + if (i + j < len) + printf("%02x ", buf[i + j]); + else + printf(" "); + + if (j == 7) + printf(" "); + } + + printf(" |"); + + for (j = 0; j < 16 && i + j < len; j++) { + + c = buf[i + j]; + printf("%c", isprint(c) ? c : '.'); + } + + printf("|\n"); + } + + printf("%08zx\n", len); } -/* \(^o^)/ - come back soon! */ -int main(int argc, char **argv) /* \ / */ -{ /* / \ */ - xpledgex("stdio", NULL); /* */ - printf("%s\n", (argc = rigged()) ? "You lose!" : "You win!"); - return argc; +static void +exit_cleanup(void) +{ + return; } diff --git a/util/libreboot-utils/mkhtemp.c b/util/libreboot-utils/mkhtemp.c index 7564800a..5be5a38a 100644 --- a/util/libreboot-utils/mkhtemp.c +++ b/util/libreboot-utils/mkhtemp.c @@ -19,10 +19,6 @@ #define _GNU_SOURCE 1 #endif -#ifdef __OpenBSD__ -#include <sys/param.h> /* pledge(2) */ -#endif - #include <sys/types.h> #include <sys/stat.h> @@ -38,6 +34,9 @@ #include "include/common.h" +static void +exit_cleanup(void); + int main(int argc, char *argv[]) { @@ -61,18 +60,14 @@ main(int argc, char *argv[]) int fd = -1; int type = MKHTEMP_FILE; - int stfu = 0; /* -q option */ + + (void) errhook(exit_cleanup); if (lbgetprogname(argv[0]) == NULL) - err_no_cleanup(stfu, errno, "could not set progname"); + err_exit(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 + /* https://man.openbsd.org/pledge.2 */ + xpledgex("stdio flock rpath wpath cpath", NULL); while ((c = getopt(argc, argv, "qdp:")) != -1) { @@ -88,7 +83,6 @@ main(int argc, char *argv[]) case 'q': /* don't print errors */ /* (exit status unchanged) */ - stfu = 1; break; default: @@ -104,14 +98,14 @@ main(int argc, char *argv[]) /* custom template e.g. foo.XXXXXXXXXXXXXXXXXXXXX */ if (template != NULL) { if (slen(template, maxlen, &tlen) < 0) - err_no_cleanup(stfu, EINVAL, + err_exit(EINVAL, "invalid template"); for (p = template + tlen; p > template && *--p == 'X'; xc++); if (xc < 3) /* the gnu mktemp errs on less than 3 */ - err_no_cleanup(stfu, EINVAL, + err_exit(EINVAL, "template must have 3 X or more on end (12+ advised"); } @@ -125,36 +119,37 @@ main(int argc, char *argv[]) if (tmpdir != NULL) { rp = realpath(tmpdir, resolved); if (rp == NULL) - err_no_cleanup(stfu, errno, "%s", tmpdir); + err_exit(errno, "%s", tmpdir); tmpdir = resolved; } if (new_tmp_common(&fd, &s, type, tmpdir, template) < 0) - err_no_cleanup(stfu, errno, "%s", s); + err_exit(errno, "%s", s); -#if defined(__OpenBSD__) && defined(OpenBSD) -#if (OpenBSD) >= 509 - if (pledge("stdio", NULL) == -1) - err_no_cleanup(stfu, errno, "pledge, exit"); -#endif -#endif + xpledgex("stdio", NULL); if (s == NULL) - err_no_cleanup(stfu, EFAULT, "bad string initialisation"); + err_exit(EFAULT, "bad string initialisation"); if (*s == '\0') - err_no_cleanup(stfu, EFAULT, "empty string initialisation"); + err_exit(EFAULT, "empty string initialisation"); if (slen(s, maxlen, &len) < 0) - err_no_cleanup(stfu, EFAULT, "unterminated string initialisiert"); + err_exit(EFAULT, "unterminated string initialisiert"); printf("%s\n", s); return EXIT_SUCCESS; err_usage: - err_no_cleanup(stfu, EINVAL, + err_exit(EINVAL, "usage: %s [-d] [-p dir] [template]\n", getnvmprogname()); +} + +static void +exit_cleanup(void) +{ + return; }/* ( >:3 ) diff --git a/util/libreboot-utils/nvmutil.c b/util/libreboot-utils/nvmutil.c index 0eed440c..bab1945d 100644 --- a/util/libreboot-utils/nvmutil.c +++ b/util/libreboot-utils/nvmutil.c @@ -6,70 +6,50 @@ * These images configure your Intel Gigabit Ethernet adapter. */ -#ifdef __OpenBSD__ -/* for pledge/unveil test: - */ -#include <sys/param.h> -#endif - #include <sys/types.h> #include <sys/stat.h> #include <errno.h> #include <fcntl.h> #include <limits.h> +#include <stdarg.h> #include <stddef.h> #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <unistd.h> #include "include/common.h" +static void +exit_cleanup(void); + int main(int argc, char *argv[]) { struct xstate *x; - struct commands *cmd; struct xfile *f; - size_t c; + (void) errhook(exit_cleanup); + if (lbgetprogname(argv[0]) == NULL) - 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(0, errno, "pledge plus unveil, main"); -#if defined(USE_URANDOM) && \ - ((USE_URANDOM) > 0) - if (unveil("/dev/null", "r") == -1) - err_no_cleanup(0, errno, "unveil r: /dev/null"); -#else - if (unveil("/dev/urandom", "r") == -1) - err_no_cleanup(0, errno, "unveil r: /dev/urandom"); -#endif -#elif (OpenBSD) >= 509 - if (pledge("stdio flock rpath wpath cpath", NULL) == -1) - err_no_cleanup(0, errno, "pledge, main"); -#endif -#endif + err_exit(errno, "could not set progname"); + + xpledgex("stdio flock rpath wpath cpath unveil", NULL); + xunveilx("/dev/urandom", "r"); #ifndef S_ISREG - err_no_cleanup(0, ECANCELED, + err_exit(ECANCELED, "Can't determine file types (S_ISREG undefined)"); #endif #if ((CHAR_BIT) != 8) - err_no_cleanup(0, ECANCELED, "Unsupported char size"); + err_exit(ECANCELED, "Unsupported char size"); #endif - x = xstart(argc, argv); - - if (x == NULL) - err_no_cleanup(0, ECANCELED, "NULL state on init"); + if ((x = xstart(argc, argv)) == NULL) + err_exit(ECANCELED, "NULL state on init"); /* parse user command */ /* TODO: CHECK ACCESSES VIA xstatus() */ @@ -79,45 +59,22 @@ main(int argc, char *argv[]) cmd = &x->cmd[x->i]; f = &x->f; -/* https://man.openbsd.org/pledge.2 - https://man.openbsd.org/unveil.2 */ -#if defined(__OpenBSD__) && defined(OpenBSD) -#if (OpenBSD) >= 604 - - if ((us.cmd[i].flags & O_ACCMODE) == O_RDONLY) { - if (unveil(us.f.fname, "r") == -1) - b0rk(errno, "%s: unveil r", us.f.fname); - } else { - if (unveil(us.f.fname, "rwc") == -1) - b0rk(errno, "%s: unveil rw", us.f.fname); - } + if ((cmd->flags & O_ACCMODE) == O_RDONLY) + xunveilx(f->fname, "r"); + else + xunveilx(f->fname, "rwc"); - if (unveil(us.f.tname, "rwc") == -1) - b0rk(errno, "unveil rwc: %s", us.f.tname); - - if (unveil(NULL, NULL) == -1) - b0rk(errno, "unveil block (rw)"); - - if (pledge("stdio flock rpath wpath cpath", NULL) == -1) - b0rk(errno, "pledge (kill unveil)"); - -#elif (OpenBSD) >= 509 - if (pledge("stdio flock rpath wpath cpath", NULL) == -1) - b0rk(errno, "pledge"); -#endif -#endif + xunveilx(f->tname, "rwc"); + xunveilx(NULL, NULL); + xpledgex("stdio flock rpath wpath cpath", NULL); if (cmd->run == NULL) - b0rk(errno, "Command not set"); - + err_exit(errno, "Command not set"); sanitize_command_list(); - open_gbe_file(); - copy_gbe(); read_checksums(); - cmd->run(); for (c = 0; c < items(x->cmd); c++) @@ -126,13 +83,17 @@ main(int argc, char *argv[]) if ((cmd->flags & O_ACCMODE) == O_RDWR) write_to_gbe_bin(); - if (exit_cleanup() == -1) - b0rk(EIO, "%s: close", f->fname); - + exit_cleanup(); if (f->io_err_gbe_bin) - b0rk(EIO, "%s: error writing final file"); + err_exit(EIO, "%s: error writing final file"); free_and_set_null(&f->tname); return EXIT_SUCCESS; } + +static void +exit_cleanup(void) +{ + return; +} |
