diff options
Diffstat (limited to 'util/libreboot-utils/lib/mkhtemp.c')
| -rw-r--r-- | util/libreboot-utils/lib/mkhtemp.c | 73 |
1 files changed, 22 insertions, 51 deletions
diff --git a/util/libreboot-utils/lib/mkhtemp.c b/util/libreboot-utils/lib/mkhtemp.c index 6b4898fd..191d657c 100644 --- a/util/libreboot-utils/lib/mkhtemp.c +++ b/util/libreboot-utils/lib/mkhtemp.c @@ -79,8 +79,8 @@ new_tmp_common(int *fd, char **path, int type, #endif struct stat st; - const char *suffix; - size_t suffix_len; + const char *templatestr; + size_t templatestr_len; size_t dirlen; size_t destlen; @@ -144,17 +144,17 @@ new_tmp_common(int *fd, char **path, int type, goto err; if (template != NULL) - suffix = template; + templatestr = template; else - suffix = "tmp.XXXXXXXXXX"; + templatestr = "tmp.XXXXXXXXXX"; - if (slen(suffix, maxlen, &suffix_len) < 0) + if (slen(templatestr, maxlen, &templatestr_len) < 0) goto err; /* sizeof adds an extra byte, useful * because we also want '.' or '/' */ - destlen = dirlen + 1 + suffix_len; + destlen = dirlen + 1 + templatestr_len; if (destlen > maxlen - 1) { errno = EOVERFLOW; goto err; @@ -168,7 +168,7 @@ new_tmp_common(int *fd, char **path, int type, memcpy(dest, tmpdir, dirlen); *(dest + dirlen) = '/'; - memcpy(dest + dirlen + 1, suffix, suffix_len); + memcpy(dest + dirlen + 1, templatestr, templatestr_len); *(dest + destlen) = '\0'; fname = dest + dirlen + 1; @@ -603,7 +603,7 @@ mkhtemp(int *fd, if_err_sys(slen(template, max_len, &len) < 0) || if_err(len >= max_len, EMSGSIZE) || - if_err_sys(slen(fname, max_len, &fname_len)) || + if_err_sys(slen(fname, max_len, &fname_len) < 0) || if_err(fname == NULL, EINVAL) || if_err(strrchr(fname, '/') != NULL, EINVAL)) return -1; @@ -611,7 +611,7 @@ mkhtemp(int *fd, for (end = template + len; /* count X */ end > template && *--end == 'X'; xc++); - if (if_err(xc < 6 || xc > len, EINVAL) || + if (if_err(xc < 3 || xc > len, EINVAL) || if_err(fname_len > len, EOVERFLOW)) return -1; @@ -622,7 +622,7 @@ mkhtemp(int *fd, if((fname_copy = malloc(fname_len + 1)) == NULL) goto err; - /* fname_copy = suffix region only; p points to trailing XXXXXX */ + /* fname_copy = templatestr region only; p points to trailing XXXXXX */ memcpy(fname_copy, template + len - fname_len, fname_len + 1); @@ -886,53 +886,30 @@ err: 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"; + size_t chx = 0; + size_t r; + /* 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; - } + if (if_err(p == NULL, EFAULT)) + return -1; 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); + /* on bsd: uses arc4random + on linux: uses getrandom + *never returns error* + */ + r = rlong(); /* always returns successful */ + if (r >= limit) + goto retry_rand; p[chx] = ch[r % (sizeof(ch) - 1)]; } @@ -940,12 +917,6 @@ retry_rand: errno = saved_errno; return 0; -err_mkhtemp_fill_random: - - if (errno == saved_errno) - errno = ECANCELED; - - return -1; } /* WARNING: **ONCE** per file. |
