diff options
Diffstat (limited to 'util/libreboot-utils')
| -rw-r--r-- | util/libreboot-utils/README.md | 9 | ||||
| -rw-r--r-- | util/libreboot-utils/include/common.h | 10 | ||||
| -rw-r--r-- | util/libreboot-utils/lib/file.c | 8 | ||||
| -rw-r--r-- | util/libreboot-utils/lib/io.c | 2 | ||||
| -rw-r--r-- | util/libreboot-utils/lib/mkhtemp.c | 4 | ||||
| -rw-r--r-- | util/libreboot-utils/lib/rand.c | 42 | ||||
| -rw-r--r-- | util/libreboot-utils/lib/state.c | 6 | ||||
| -rw-r--r-- | util/libreboot-utils/lib/string.c | 35 | ||||
| -rw-r--r-- | util/libreboot-utils/lottery.c | 93 | ||||
| -rw-r--r-- | util/libreboot-utils/nvmutil.c | 2 |
10 files changed, 122 insertions, 89 deletions
diff --git a/util/libreboot-utils/README.md b/util/libreboot-utils/README.md index 9a40d5ce..6e94035b 100644 --- a/util/libreboot-utils/README.md +++ b/util/libreboot-utils/README.md @@ -24,9 +24,16 @@ the kernel/system), voluntarily error out (halt all operation) if accessing files you don't own - that's why sticky bits are checked for example, even when you're root. +It... blocks symlinks, relative paths, attempts to prevent +directory escape (outside of the directory that the file +you're creating is in), basically implementing an analog +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. +over traditional mktemp. Written in C89, and the plan is +very much to keep this code portable over time - patches +very much welcome. i.e. please read the source code diff --git a/util/libreboot-utils/include/common.h b/util/libreboot-utils/include/common.h index 0c8fbd3d..77672846 100644 --- a/util/libreboot-utils/include/common.h +++ b/util/libreboot-utils/include/common.h @@ -22,6 +22,10 @@ #include <sys/syscall.h> #endif +#ifdef __OpenBSD__ /* for pledge */ +#include <unistd.h> +#endif + #define items(x) (sizeof((x)) / sizeof((x)[0])) /* system prototypes @@ -369,6 +373,8 @@ void write_mac_part(size_t partnum); /* string functions */ +int xunveilx(const char *path, const char *permissions); +int xpledgex(const char *promises, const char *execpromises); int slen(const char *scmp, size_t maxlen, size_t *rval); int scmp(const char *a, const char *b, @@ -391,7 +397,7 @@ 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); -int win_lottery(char **buf); +size_t rsize(size_t n); /* Helper functions for command: dump */ @@ -537,7 +543,7 @@ 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_if_null(char **buf); +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); diff --git a/util/libreboot-utils/lib/file.c b/util/libreboot-utils/lib/file.c index 5fdef7b3..3ca50889 100644 --- a/util/libreboot-utils/lib/file.c +++ b/util/libreboot-utils/lib/file.c @@ -153,7 +153,7 @@ fsync_dir(const char *path) goto err_fsync_dir; } - free_if_null(&dirbuf); + free_and_set_null(&dirbuf); errno = saved_errno; return 0; @@ -163,7 +163,7 @@ err_fsync_dir: if (errno == saved_errno) errno = EIO; - free_if_null(&dirbuf); + free_and_set_null(&dirbuf); close_no_err(&dirfd); return -1; @@ -581,7 +581,7 @@ try_err(int loop_err, int errval) } void -free_if_null(char **buf) +free_and_set_null(char **buf) { if (buf == NULL || *buf == NULL) return; @@ -902,7 +902,7 @@ fs_dirname_basename(const char *path, *base = buf; } else { errno = EINVAL; - free_if_null(&buf); + free_and_set_null(&buf); return -1; } diff --git a/util/libreboot-utils/lib/io.c b/util/libreboot-utils/lib/io.c index d05adbcc..1f2064a0 100644 --- a/util/libreboot-utils/lib/io.c +++ b/util/libreboot-utils/lib/io.c @@ -266,7 +266,7 @@ write_to_gbe_bin(void) /* removed by rename */ - free_if_null(&f->tname); + free_and_set_null(&f->tname); } } diff --git a/util/libreboot-utils/lib/mkhtemp.c b/util/libreboot-utils/lib/mkhtemp.c index 0e0169e4..c913ce6c 100644 --- a/util/libreboot-utils/lib/mkhtemp.c +++ b/util/libreboot-utils/lib/mkhtemp.c @@ -184,7 +184,7 @@ err: else saved_errno = errno = EIO; - free_if_null(&dest); + free_and_set_null(&dest); close_no_err(&dirfd); close_no_err(fd); @@ -619,7 +619,7 @@ err: close_no_err(fd); success: - free_if_null(&fname_copy); + free_and_set_null(&fname_copy); return (*fd >= 0) ? *fd : -1; } diff --git a/util/libreboot-utils/lib/rand.c b/util/libreboot-utils/lib/rand.c index 3a0a94bf..3155eec3 100644 --- a/util/libreboot-utils/lib/rand.c +++ b/util/libreboot-utils/lib/rand.c @@ -72,37 +72,20 @@ * or your program dies. */ -int -win_lottery(char **buf) /* are u lucky? */ +void * +rmalloc(size_t *rval) { - size_t size = 0; - int rval; - - char *s1 = rmalloc(&size); - char *s2 = rmalloc(&size); - - if (scmp(s1, s2, BUFSIZ + 2, &rval) >= 0 && - rval == 0) - rval = 1; /* winner! */ - else - rval = 0; - - (void) scat(s1, s2, BUFSIZ << 1, buf); - - free_if_null(&s1); - free_if_null(&s2); - - return rval; + return if_err(rval == NULL, EFAULT) ? + NULL : mkrstr(*rval = rsize(BUFSIZ)); } -void * -rmalloc(size_t *rval) +size_t +rsize(size_t n) { - if (if_err(rval == NULL, EFAULT)) - return NULL; + size_t rval = SIZE_MAX; + for (; rval >= SIZE_MAX - (SIZE_MAX % n); rset(&rval, sizeof(rval))); - rset(rval, sizeof(*rval)); - return mkrstr(*rval %= BUFSIZ); + return rval % n; } char * @@ -114,7 +97,7 @@ mkrstr(size_t n) /* emulates spkmodem-decode */ if (n == 0) err_no_cleanup(0, EPERM, "mkrbuf: zero-byte request"); - if (n == SIZE_MAX) + if (n >= SIZE_MAX - 1) err_no_cleanup(0, EOVERFLOW, "mkrbuf: overflow"); if (if_err((s = mkrbuf(n + 1)) == NULL, EFAULT)) @@ -132,11 +115,14 @@ mkrstr(size_t n) /* emulates spkmodem-decode */ void * mkrbuf(size_t n) { - void *buf; + 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"); diff --git a/util/libreboot-utils/lib/state.c b/util/libreboot-utils/lib/state.c index 42d060b7..41c851fb 100644 --- a/util/libreboot-utils/lib/state.c +++ b/util/libreboot-utils/lib/state.c @@ -139,7 +139,7 @@ xstart(int argc, char *argv[]) if (us.f.tmpbase == NULL) err_no_cleanup(0, errno, "strdup tmpbase"); - free_if_null(&tmpdir); + free_and_set_null(&tmpdir); if (us.f.tname == NULL) err_no_cleanup(0, errno, "x->f.tname null"); @@ -219,8 +219,8 @@ exit_cleanup(void) close_err = 1; close_no_err(&f->dirfd); - free_if_null(&f->base); - free_if_null(&f->tmpbase); + free_and_set_null(&f->base); + free_and_set_null(&f->tmpbase); } if (saved_errno) diff --git a/util/libreboot-utils/lib/string.c b/util/libreboot-utils/lib/string.c index b639f0a4..c6e09752 100644 --- a/util/libreboot-utils/lib/string.c +++ b/util/libreboot-utils/lib/string.c @@ -321,15 +321,28 @@ lbgetprogname(char *argv0) return progname; } +int +xpledgex(const char *promises, const char *execpromises) +{ + int saved_errno = errno; + (void) promises, (void) execpromises, (void) saved_errno; +#ifdef __OpenBSD__ + if (pledge(promises, execpromises) == -1) + err_no_cleanup(0, errno, "pledge"); +#endif + errno = saved_errno; + return 0; +} - - - - - - - - - - - +int +xunveilx(const char *path, const char *permissions) +{ + int saved_errno = errno; + (void) path, (void) permissions, (void) saved_errno; +#ifdef __OpenBSD__ + if (pledge(promises, execpromises) == -1) + err_no_cleanup(0, errno, "pledge"); +#endif + errno = saved_errno; + return 0; +} diff --git a/util/libreboot-utils/lottery.c b/util/libreboot-utils/lottery.c index 8157d7a9..4b607117 100644 --- a/util/libreboot-utils/lottery.c +++ b/util/libreboot-utils/lottery.c @@ -1,41 +1,62 @@ -/* SPDX-License-Identifier: MIT - * Copyright (c) 2026 Leah Rowe <leah@libreboot.org> - */ - -#ifdef __OpenBSD__ -#include <sys/param.h> /* pledge(2) */ -#endif - +/* SPDX-License-Identifier: MIT ( >:3 ) + * Copyright (c) 2026 Leah Rowe <leah@libreboot.org> /| |\ + / \ */ #include <stdio.h> -#include <stdlib.h> -#include "include/common.h" +#include <stdint.h> +#include <stdlib.h> /* (^.>) - are u lucky? */ +#include <string.h> /* \| /= */ +#include "include/common.h" /* l \ */ -int -main(int argc, char *argv[]) +#define len_hell(x, y) ((((x) - (y)) < BUFSIZ) ? ((x) - (y)) : BUFSIZ) + +static int rigged(void) { - char *s1 = NULL; - int rval = 0; - -#if defined(__OpenBSD__) && defined(OpenBSD) -#if (OpenBSD) >= 509 - if (pledge("stdio", NULL) == -1) - err_no_cleanup(0, errno, "openbsd won it"); -#endif -#endif - setvbuf(stdout, NULL, _IONBF, 0); - - if (win_lottery(&s1)) - rval = 1; - - if (s1 != NULL) { - printf("%s\n\n", s1); - free(s1); + size_t size[5] = { 0, 0, 0, SIZE_MAX, SIZE_MAX}; + char *b1 = NULL, *b2 = NULL; + char *s = NULL; +again: + if (!size[3]) { + if (!size[4]) + return 0; /* <--- WINNER!!! */ + 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 again; /* / \ */ + + if (s == NULL) { + if ((s = malloc(BUFSIZ)) == NULL) + goto out; } - printf("%s\n", rval ? "You won!" : "You lose! Sorry!"); - return rval? EXIT_SUCCESS : EXIT_FAILURE; -}/* - - ( >:3 ) - /| |\ - / \ */ + 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; + } + + goto again; +out: + free_and_set_null(&b1); + free_and_set_null(&b2); + free_and_set_null(&s); + + return 1; +} +/* \(^o^)/ - come again soon! */ +int main(int argc, char **argv) /* \ / */ +{ /* / \ */ + xpledgex("stdio", NULL); /* */ + printf("%s", (argc = rigged()) ? "You lose!\n" : ""); + + return argc; +} diff --git a/util/libreboot-utils/nvmutil.c b/util/libreboot-utils/nvmutil.c index 313390c0..0eed440c 100644 --- a/util/libreboot-utils/nvmutil.c +++ b/util/libreboot-utils/nvmutil.c @@ -132,7 +132,7 @@ main(int argc, char *argv[]) if (f->io_err_gbe_bin) b0rk(EIO, "%s: error writing final file"); - free_if_null(&f->tname); + free_and_set_null(&f->tname); return EXIT_SUCCESS; } |
