From 23c0672c281a949c254ef0c173eab987ab876e29 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Mon, 11 Jan 2021 16:46:12 -0800 Subject: [PATCH] tempname: consume less entropy Derived from a glibc patch proposed by Adhemerval Zanella in: https://sourceware.org/pipermail/libc-alpha/2021-January/121302.html * lib/tempname.c: Include stdbool.h. (random_bits): New arg use_getrandom. (try_tempname_len): Skip getrandom on the first try, unless __GT_NOCREATE. * modules/tempname (Depends-on): Add stdbool. --- ChangeLog | 11 +++++++++++ lib/tempname.c | 17 ++++++++++++++--- modules/tempname | 1 + 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index c6f5295b4..0d0144242 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2021-01-11 Paul Eggert + + tempname: consume less entropy + Derived from a glibc patch proposed by Adhemerval Zanella in: + https://sourceware.org/pipermail/libc-alpha/2021-January/121302.html + * lib/tempname.c: Include stdbool.h. + (random_bits): New arg use_getrandom. + (try_tempname_len): Skip getrandom on the first try, + unless __GT_NOCREATE. + * modules/tempname (Depends-on): Add stdbool. + 2021-01-10 Bruno Haible lchmod-tests: Fix link error. diff --git a/lib/tempname.c b/lib/tempname.c index f199b25a7..5f804b38d 100644 --- a/lib/tempname.c +++ b/lib/tempname.c @@ -22,6 +22,7 @@ #include #include +#include #include @@ -77,11 +78,11 @@ typedef uint_fast64_t random_value; #define BASE_62_POWER (62LL * 62 * 62 * 62 * 62 * 62 * 62 * 62 * 62 * 62) static random_value -random_bits (random_value var) +random_bits (random_value var, bool use_getrandom) { random_value r; /* Without GRND_NONBLOCK it can be blocked for minutes on some systems. */ - if (__getrandom (&r, sizeof r, GRND_NONBLOCK) == sizeof r) + if (use_getrandom && __getrandom (&r, sizeof r, GRND_NONBLOCK) == sizeof r) return r; #if _LIBC || (defined CLOCK_MONOTONIC && HAVE_CLOCK_GETTIME) /* Add entropy if getrandom did not work. */ @@ -269,6 +270,13 @@ try_tempname_len (char *tmpl, int suffixlen, void *args, /* How many random base-62 digits can currently be extracted from V. */ int vdigits = 0; + /* Whether to consume entropy when acquiring random bits. On the + first try it's worth the entropy cost with __GT_NOCREATE, which + is inherently insecure and can use the entropy to make it a bit + less secure. On the (rare) second and later attempts it might + help against DoS attacks. */ + bool use_getrandom = tryfunc == try_nocreate; + /* Least unfair value for V. If V is less than this, V can generate BASE_62_DIGITS digits fairly. Otherwise it might be biased. */ random_value const unfair_min @@ -292,7 +300,10 @@ try_tempname_len (char *tmpl, int suffixlen, void *args, if (vdigits == 0) { do - v = random_bits (v); + { + v = random_bits (v, use_getrandom); + use_getrandom = true; + } while (unfair_min <= v); vdigits = BASE_62_DIGITS; diff --git a/modules/tempname b/modules/tempname index 27b0d3d23..4779735d9 100644 --- a/modules/tempname +++ b/modules/tempname @@ -17,6 +17,7 @@ libc-config lstat mkdir stdalign +stdbool stdint sys_stat time -- 2.27.0