mirror of
https://codeberg.org/libreboot/lbmk.git
synced 2026-07-18 04:22:15 +02:00
libreboot-utils: simplify random tmpdir namegen
generalise it in rand.c because this logic will be useful for other programs in the future. Signed-off-by: Leah Rowe <leah@libreboot.org>
This commit is contained in:
@@ -399,7 +399,7 @@ void spew_hex(const void *data, size_t len);
|
|||||||
void *rmalloc(size_t n);
|
void *rmalloc(size_t n);
|
||||||
void rset(void *buf, size_t n);
|
void rset(void *buf, size_t n);
|
||||||
void *rmalloc(size_t n);
|
void *rmalloc(size_t n);
|
||||||
char *mkrstr(size_t n);
|
char *rchars(size_t n);
|
||||||
size_t rsize(size_t n);
|
size_t rsize(size_t n);
|
||||||
|
|
||||||
/* Helper functions for command: dump
|
/* Helper functions for command: dump
|
||||||
@@ -524,7 +524,6 @@ mkhtemp_tmpfile_linux(int dirfd,
|
|||||||
int mkhtemp(int *fd, struct stat *st,
|
int mkhtemp(int *fd, struct stat *st,
|
||||||
char *template, int dirfd, const char *fname,
|
char *template, int dirfd, const char *fname,
|
||||||
struct stat *st_dir_initial, int type);
|
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 world_writeable_and_sticky(const char *s,
|
||||||
int sticky_allowed, int always_sticky);
|
int sticky_allowed, int always_sticky);
|
||||||
int same_dir(const char *a, const char *b);
|
int same_dir(const char *a, const char *b);
|
||||||
|
|||||||
@@ -537,20 +537,6 @@ try_err(int loop_err, int errval)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
void
|
||||||
open_on_eintr(const char *path,
|
open_on_eintr(const char *path,
|
||||||
int *fd, int flags, mode_t mode,
|
int *fd, int flags, mode_t mode,
|
||||||
|
|||||||
@@ -627,6 +627,7 @@ mkhtemp_try_create(int dirfd,
|
|||||||
struct stat st_open;
|
struct stat st_open;
|
||||||
int saved_errno = errno;
|
int saved_errno = errno;
|
||||||
int rval = -1;
|
int rval = -1;
|
||||||
|
char *rstr = NULL;
|
||||||
|
|
||||||
int file_created = 0;
|
int file_created = 0;
|
||||||
int dir_created = 0;
|
int dir_created = 0;
|
||||||
@@ -636,8 +637,13 @@ mkhtemp_try_create(int dirfd,
|
|||||||
if_err(*fd >= 0, EEXIST))
|
if_err(*fd >= 0, EEXIST))
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
if (if_err_sys(mkhtemp_fill_random(p, xc) < 0) ||
|
/* TODO: potential infinite loop under entropy failure.
|
||||||
if_err_sys(fd_verify_dir_identity(dirfd, st_dir_initial) < 0))
|
* 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;
|
goto err;
|
||||||
|
|
||||||
if (type == MKHTEMP_FILE) {
|
if (type == MKHTEMP_FILE) {
|
||||||
@@ -765,6 +771,7 @@ mkhtemp_tmpfile_linux(int dirfd,
|
|||||||
int tmpfd = -1;
|
int tmpfd = -1;
|
||||||
size_t retries;
|
size_t retries;
|
||||||
int linked = 0;
|
int linked = 0;
|
||||||
|
char *rstr = NULL;
|
||||||
|
|
||||||
if (fd == NULL || st == NULL ||
|
if (fd == NULL || st == NULL ||
|
||||||
fname_copy == NULL || p == NULL ||
|
fname_copy == NULL || p == NULL ||
|
||||||
@@ -785,8 +792,8 @@ mkhtemp_tmpfile_linux(int dirfd,
|
|||||||
|
|
||||||
for (retries = 0; retries < MKHTEMP_RETRY_MAX; retries++) {
|
for (retries = 0; retries < MKHTEMP_RETRY_MAX; retries++) {
|
||||||
|
|
||||||
if (mkhtemp_fill_random(p, xc) < 0)
|
memcpy(p, rstr = rchars(xc), xc);
|
||||||
goto err;
|
free_and_set_null(&rstr);
|
||||||
|
|
||||||
if (fd_verify_dir_identity(dirfd,
|
if (fd_verify_dir_identity(dirfd,
|
||||||
st_dir_initial) < 0)
|
st_dir_initial) < 0)
|
||||||
@@ -832,43 +839,6 @@ err:
|
|||||||
}
|
}
|
||||||
#endif
|
#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.
|
/* WARNING: **ONCE** per file.
|
||||||
*
|
*
|
||||||
* some of these checks will trip up
|
* some of these checks will trip up
|
||||||
|
|||||||
@@ -72,6 +72,36 @@
|
|||||||
* or your program dies.
|
* 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
|
size_t
|
||||||
rsize(size_t n)
|
rsize(size_t n)
|
||||||
{
|
{
|
||||||
@@ -85,30 +115,6 @@ rsize(size_t n)
|
|||||||
return rval % 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 *
|
void *
|
||||||
rmalloc(size_t n)
|
rmalloc(size_t n)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -19,6 +19,20 @@
|
|||||||
|
|
||||||
#include "../include/common.h"
|
#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.
|
/* safe(ish) malloc.
|
||||||
|
|
||||||
use this and free_and_set_null()
|
use this and free_and_set_null()
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ main(int argc, char **argv)
|
|||||||
|
|
||||||
if (argc < 2) /* no spew */
|
if (argc < 2) /* no spew */
|
||||||
spew_hex(buf, BUFSIZ);
|
spew_hex(buf, BUFSIZ);
|
||||||
free(buf);
|
free_and_set_null(&buf);
|
||||||
|
|
||||||
fprintf(stderr, "\n%s\n", same ? "You win!" : "You lose!");
|
fprintf(stderr, "\n%s\n", same ? "You win!" : "You lose!");
|
||||||
return same ^ 1;
|
return same ^ 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user