diff options
| author | Leah Rowe <leah@libreboot.org> | 2026-03-22 19:27:37 +0000 |
|---|---|---|
| committer | Leah Rowe <leah@libreboot.org> | 2026-03-22 19:27:37 +0000 |
| commit | b8ababa2beb1b5466b6ba2062e52be36a73d654e (patch) | |
| tree | d284f3579f93d45eb820c2b8e58be0b7fe389a11 /util | |
| parent | 535ab29debb15cdaa4c35de4938b6f3d3ed073b9 (diff) | |
WIP: split out rand fill on mkhtemp
Signed-off-by: Leah Rowe <leah@libreboot.org>
Diffstat (limited to 'util')
| -rw-r--r-- | util/nvmutil/include/common.h | 1 | ||||
| -rw-r--r-- | util/nvmutil/lib/file.c | 130 |
2 files changed, 77 insertions, 54 deletions
diff --git a/util/nvmutil/include/common.h b/util/nvmutil/include/common.h index cb148368..d433197d 100644 --- a/util/nvmutil/include/common.h +++ b/util/nvmutil/include/common.h @@ -482,6 +482,7 @@ char *new_tmplate(int *fd, int local, const char *path); int mkhtemp(int *fd, struct stat *st, char *template, int dirfd, const char *fname, struct stat *st_dir_initial); +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/nvmutil/lib/file.c b/util/nvmutil/lib/file.c index 20c49164..14ece22a 100644 --- a/util/nvmutil/lib/file.c +++ b/util/nvmutil/lib/file.c @@ -796,28 +796,12 @@ int mkhtemp(int *fd, * it doesn't make tmp*dirs* */ - size_t retries = 0; -#if !(defined(MAX_MKHTEMP_RETRIES) && \ - (MAX_MKHTEMP_RETRIES) >= 128) - size_t max_retries = 200; -#else - size_t max_retries = 128; -#endif - - size_t chx = 0; size_t len = 0; char *p = NULL; char *template_copy = NULL; size_t xc = 0; - static char ch[] = - "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; - size_t limit = - ((size_t)-1) - (((size_t)-1) % (sizeof(ch) - 1)); - - int rand_failures = 0; - size_t r; #if defined(PATH_LEN) && \ (PATH_LEN) >= 256 @@ -833,8 +817,6 @@ int mkhtemp(int *fd, mode_t old_umask; - int saved_rand_error = 0; - char *fname_copy = NULL; size_t fname_len = 0; @@ -850,6 +832,15 @@ int mkhtemp(int *fd, */ struct stat st_dir_now; + size_t retries = 0; +#if !(defined(MAX_MKHTEMP_RETRIES) && \ + (MAX_MKHTEMP_RETRIES) >= 128) + size_t max_retries = 300; +#else + size_t max_retries = 128; +#endif + + if (fname == NULL || st_dir_initial == NULL) { @@ -990,42 +981,8 @@ int mkhtemp(int *fd, for (retries = 0; retries < max_retries; retries++) { - for (chx = 0; chx < xc; chx++) { - - /* clamp rand to prevent modulo bias - * (reduced risk of entropy leak) - */ - - do { - saved_rand_error = errno; - - rand_failures = 0; -retry_rand: - errno = 0; - - /* on bsd: uses arc4random - on linux: uses getrandom - on OLD linux: /dev/urandom - on old/other unix: /dev/urandom - */ - r = rlong(); - - if (errno > 0) { - - if (++rand_failures <= 8) - goto retry_rand; - - goto err_mkhtemp; - } - - rand_failures = 0; - - errno = saved_rand_error; - - } while (r >= limit); - - p[chx] = ch[r % (sizeof(ch) - 1)]; - } + if (mkhtemp_fill_random(p, xc) < 0) + goto err_mkhtemp; /* * use the file descriptor instead. @@ -1137,6 +1094,71 @@ err_mkhtemp: return -1; } +int +mkhtemp_fill_random(char *p, size_t xc) +{ + size_t chx = 0; + int rand_failures = 0; + + size_t r; + + int saved_rand_error = 0; + static char ch[] = + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + + /* clamp rand to prevent modulo bias + * (reduced risk of entropy leak) + */ + size_t limit = ((size_t)-1) - (((size_t)-1) % (sizeof(ch) - 1)); + + int saved_errno = errno; + + if (p == NULL) { + errno = EFAULT; + goto err_mkhtemp_fill_random; + } + + for (chx = 0; chx < xc; chx++) { + + do { + saved_rand_error = errno; + rand_failures = 0; +retry_rand: + errno = 0; + + /* on bsd: uses arc4random + on linux: uses getrandom + on OLD linux: /dev/urandom + on old/other unix: /dev/urandom + */ + r = rlong(); + + if (errno > 0) { + if (++rand_failures <= 8) + goto retry_rand; + + goto err_mkhtemp_fill_random; + } + + rand_failures = 0; + errno = saved_rand_error; + + } while (r >= limit); + + p[chx] = ch[r % (sizeof(ch) - 1)]; + } + + errno = saved_errno; + return 0; + +err_mkhtemp_fill_random: + + if (errno == saved_errno) + errno = ECANCELED; + + return -1; +} + /* why doesn't literally every libc have this? |
