[2/2] posix: Improve randomness on try_tempname_len

Message ID 20200929125546.3413273-2-adhemerval.zanella@linaro.org
State Superseded
Headers
Series [1/2] posix: Sync tempname with gnulib [BZ #26648] |

Commit Message

Adhemerval Zanella Sept. 29, 2020, 12:55 p.m. UTC
  For __GT_NOCREATE (mktemp, tempnam, tmpnam) getrandom is also used
on first try, otherwise randomness is obtained using the clock plus
a linear congruential generator.

Also for getrandom GRND_NONBLOCK is used to avoid blocking indefinitely
on some older kernels.

Checked on x86_64-linux-gnu.
---
 sysdeps/posix/tempname.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)
  

Comments

Adhemerval Zanella Oct. 26, 2020, 7:46 p.m. UTC | #1
Ping.

On 29/09/2020 09:55, Adhemerval Zanella wrote:
> For __GT_NOCREATE (mktemp, tempnam, tmpnam) getrandom is also used
> on first try, otherwise randomness is obtained using the clock plus
> a linear congruential generator.
> 
> Also for getrandom GRND_NONBLOCK is used to avoid blocking indefinitely
> on some older kernels.
> 
> Checked on x86_64-linux-gnu.
> ---
>  sysdeps/posix/tempname.c | 10 ++++++----
>  1 file changed, 6 insertions(+), 4 deletions(-)
> 
> diff --git a/sysdeps/posix/tempname.c b/sysdeps/posix/tempname.c
> index 03426c23cf..5d6cf261fa 100644
> --- a/sysdeps/posix/tempname.c
> +++ b/sysdeps/posix/tempname.c
> @@ -76,10 +76,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;
> -  if (__getrandom (&r, sizeof r, 0) == sizeof r)
> +  /* Without GRND_NONBLOCK it can be blocked for minutes on some systems.  */
> +  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 is not supported.  */
> @@ -263,9 +264,10 @@ try_tempname_len (char *tmpl, int suffixlen, void *args,
>       some entropy from the ASLR and ignore possible bits from the stack
>       alignment.  */
>    random_value v = ((uintptr_t) &v) / alignof (max_align_t);
> +  v = random_bits (v, tryfunc == try_nocreate);
>  
>    /* How many random base-62 digits can currently be extracted from V.  */
> -  int vdigits = 0;
> +  int vdigits = BASE_62_DIGITS;
>  
>    /* Least unfair value for V.  If V is less than this, V can generate
>       BASE_62_DIGITS digits fairly.  Otherwise it might be biased.  */
> @@ -290,7 +292,7 @@ try_tempname_len (char *tmpl, int suffixlen, void *args,
>            if (vdigits == 0)
>              {
>                do
> -                v = random_bits (v);
> +                v = random_bits (v, true);
>                while (unfair_min <= v);
>  
>                vdigits = BASE_62_DIGITS;
>
  

Patch

diff --git a/sysdeps/posix/tempname.c b/sysdeps/posix/tempname.c
index 03426c23cf..5d6cf261fa 100644
--- a/sysdeps/posix/tempname.c
+++ b/sysdeps/posix/tempname.c
@@ -76,10 +76,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;
-  if (__getrandom (&r, sizeof r, 0) == sizeof r)
+  /* Without GRND_NONBLOCK it can be blocked for minutes on some systems.  */
+  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 is not supported.  */
@@ -263,9 +264,10 @@  try_tempname_len (char *tmpl, int suffixlen, void *args,
      some entropy from the ASLR and ignore possible bits from the stack
      alignment.  */
   random_value v = ((uintptr_t) &v) / alignof (max_align_t);
+  v = random_bits (v, tryfunc == try_nocreate);
 
   /* How many random base-62 digits can currently be extracted from V.  */
-  int vdigits = 0;
+  int vdigits = BASE_62_DIGITS;
 
   /* Least unfair value for V.  If V is less than this, V can generate
      BASE_62_DIGITS digits fairly.  Otherwise it might be biased.  */
@@ -290,7 +292,7 @@  try_tempname_len (char *tmpl, int suffixlen, void *args,
           if (vdigits == 0)
             {
               do
-                v = random_bits (v);
+                v = random_bits (v, true);
               while (unfair_min <= v);
 
               vdigits = BASE_62_DIGITS;