diff options
| -rw-r--r-- | util/libreboot-utils/include/common.h | 3 | ||||
| -rw-r--r-- | util/libreboot-utils/lib/file.c | 14 | ||||
| -rw-r--r-- | util/libreboot-utils/lib/mkhtemp.c | 52 | ||||
| -rw-r--r-- | util/libreboot-utils/lib/rand.c | 54 | ||||
| -rw-r--r-- | util/libreboot-utils/lib/string.c | 14 | ||||
| -rw-r--r-- | util/libreboot-utils/lottery.c | 2 |
6 files changed, 57 insertions, 82 deletions
diff --git a/util/libreboot-utils/include/common.h b/util/libreboot-utils/include/common.h index b5b251d3..4b736808 100644 --- a/util/libreboot-utils/include/common.h +++ b/util/libreboot-utils/include/common.h @@ -399,7 +399,7 @@ void spew_hex(const void *data, size_t len); void *rmalloc(size_t n); void rset(void *buf, size_t n); void *rmalloc(size_t n); -char *mkrstr(size_t n); +char *rchars(size_t n); size_t rsize(size_t n); /* Helper functions for command: dump @@ -524,7 +524,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..48eb37ed 100644 --- a/util/libreboot-utils/lib/file.c +++ b/util/libreboot-utils/lib/file.c @@ -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) diff --git a/util/libreboot-utils/lib/mkhtemp.c b/util/libreboot-utils/lib/mkhtemp.c index 61479b25..72942868 100644 --- a/util/libreboot-utils/lib/mkhtemp.c +++ b/util/libreboot-utils/lib/mkhtemp.c @@ -627,6 +627,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 +637,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 +771,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 +792,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 +839,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/rand.c b/util/libreboot-utils/lib/rand.c index 2cb0f56d..2aa0de3a 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,30 +115,6 @@ 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, "rmalloc: zero-byte request"); - - if (n >= SIZE_MAX - 1) - err_exit(EOVERFLOW, "rmalloc: overflow"); - - if (if_err((s = rmalloc(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 * rmalloc(size_t n) { diff --git a/util/libreboot-utils/lib/string.c b/util/libreboot-utils/lib/string.c index 6a372dcf..c3cf4519 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() diff --git a/util/libreboot-utils/lottery.c b/util/libreboot-utils/lottery.c index 87637123..48565c87 100644 --- a/util/libreboot-utils/lottery.c +++ b/util/libreboot-utils/lottery.c @@ -33,7 +33,7 @@ main(int argc, char **argv) if (argc < 2) /* no spew */ spew_hex(buf, BUFSIZ); - free(buf); + free_and_set_null(&buf); fprintf(stderr, "\n%s\n", same ? "You win!" : "You lose!"); return same ^ 1; |
