bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] tempname: help merge with glibc


From: Paul Eggert
Subject: [PATCH] tempname: help merge with glibc
Date: Thu, 10 Sep 2020 00:03:30 -0700

Inspired by draft patches by Adhemerval Zanella in:
https://sourceware.org/pipermail/libc-alpha/2020-September/117501.html
https://sourceware.org/pipermail/libc-alpha/2020-September/117502.html
* lib/tempname.c: Include stdalign.h, time.h.
If _LIBC, do not include random-bits.h.
(__getrandom, __clock_gettime64, __timespec64) [!_LIBC]: New macros.
(RANDOM_BITS): Remove, replacing with ...
(random_bits): ... this new static function.  All uses changed.
Add entropy each time if getrandom is not supported.
(RANDOM_VALUE, BASE_62_DIGITS, BASE_62_POWER):
Assume 64-bit support a la C99.
(try_tempname_len): Take advantage of ASLR when initializing
random value.
* modules/tempname (Depends-on): Add clock-time, stdalign, time.
---
 ChangeLog        | 16 ++++++++++++++++
 lib/tempname.c   | 49 +++++++++++++++++++++++++++++-------------------
 modules/tempname |  3 +++
 3 files changed, 49 insertions(+), 19 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index c554e5672..8b6f62bb1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,21 @@
 2020-09-09  Paul Eggert  <eggert@cs.ucla.edu>
 
+       tempname: help merge with glibc
+       Inspired by draft patches by Adhemerval Zanella in:
+       https://sourceware.org/pipermail/libc-alpha/2020-September/117501.html
+       https://sourceware.org/pipermail/libc-alpha/2020-September/117502.html
+       * lib/tempname.c: Include stdalign.h, time.h.
+       If _LIBC, do not include random-bits.h.
+       (__getrandom, __clock_gettime64, __timespec64) [!_LIBC]: New macros.
+       (RANDOM_BITS): Remove, replacing with ...
+       (random_bits): ... this new static function.  All uses changed.
+       Add entropy each time if getrandom is not supported.
+       (RANDOM_VALUE, BASE_62_DIGITS, BASE_62_POWER):
+       Assume 64-bit support a la C99.
+       (try_tempname_len): Take advantage of ASLR when initializing
+       random value.
+       * modules/tempname (Depends-on): Add clock-time, stdalign, time.
+
        getcwd: merge recent glibc changes
        * lib/getcwd.c (GETCWD_RETURN_TYPE) [!_LIBC]: New macro.
        (__getcwd, getcwd) [_LIBC && !GETCWD_RETURN_TYPE]: Add aliases.
diff --git a/lib/tempname.c b/lib/tempname.c
index 9219ee66a..03426c23c 100644
--- a/lib/tempname.c
+++ b/lib/tempname.c
@@ -47,9 +47,11 @@
 #include <string.h>
 
 #include <fcntl.h>
+#include <stdalign.h>
 #include <stdint.h>
 #include <sys/random.h>
 #include <sys/stat.h>
+#include <time.h>
 
 #if _LIBC
 # define struct_stat64 struct stat64
@@ -60,27 +62,33 @@
 # define __mkdir mkdir
 # define __open open
 # define __lxstat64(version, file, buf) lstat (file, buf)
+# define __getrandom getrandom
+# define __clock_gettime64 clock_gettime
+# define __timespec64 timespec
 #endif
 
-#ifdef _LIBC
-# include <random-bits.h>
-# define RANDOM_BITS(Var) ((Var) = random_bits ())
-typedef uint32_t random_value;
-# define RANDOM_VALUE_MAX UINT32_MAX
-# define BASE_62_DIGITS 5 /* 62**5 < UINT32_MAX */
-# define BASE_62_POWER (62 * 62 * 62 * 62 * 62) /* 2**BASE_62_DIGITS */
-#else
 /* Use getrandom if it works, falling back on a 64-bit linear
-   congruential generator that starts with whatever Var's value
-   happens to be.  */
-# define RANDOM_BITS(Var) \
-    ((void) (getrandom (&(Var), sizeof (Var), 0) == sizeof (Var) \
-             || ((Var) = 2862933555777941757 * (Var) + 3037000493)))
+   congruential generator that starts with Var's value
+   mixed in with a clock's low-order bits if available.  */
 typedef uint_fast64_t random_value;
-# define RANDOM_VALUE_MAX UINT_FAST64_MAX
-# define BASE_62_DIGITS 10 /* 62**10 < UINT_FAST64_MAX */
-# define BASE_62_POWER (62LL * 62 * 62 * 62 * 62 * 62 * 62 * 62 * 62 * 62)
+#define RANDOM_VALUE_MAX UINT_FAST64_MAX
+#define BASE_62_DIGITS 10 /* 62**10 < UINT_FAST64_MAX */
+#define BASE_62_POWER (62LL * 62 * 62 * 62 * 62 * 62 * 62 * 62 * 62 * 62)
+
+static random_value
+random_bits (random_value var)
+{
+  random_value r;
+  if (__getrandom (&r, sizeof r, 0) == sizeof r)
+    return r;
+#if _LIBC || (defined CLOCK_MONOTONIC && HAVE_CLOCK_GETTIME)
+  /* Add entropy if getrandom is not supported.  */
+  struct __timespec64 tv;
+  __clock_gettime64 (CLOCK_MONOTONIC, &tv);
+  var ^= tv.tv_nsec;
 #endif
+  return 2862933555777941757 * var + 3037000493;
+}
 
 #if _LIBC
 /* Return nonzero if DIR is an existent directory.  */
@@ -250,8 +258,11 @@ try_tempname_len (char *tmpl, int suffixlen, void *args,
   unsigned int attempts = ATTEMPTS_MIN;
 #endif
 
-  /* A random variable.  */
-  random_value v;
+  /* A random variable.  The initial value is used only the for fallback path
+     on 'random_bits' on 'getrandom' failure.  Its initial value tries to use
+     some entropy from the ASLR and ignore possible bits from the stack
+     alignment.  */
+  random_value v = ((uintptr_t) &v) / alignof (max_align_t);
 
   /* How many random base-62 digits can currently be extracted from V.  */
   int vdigits = 0;
@@ -279,7 +290,7 @@ try_tempname_len (char *tmpl, int suffixlen, void *args,
           if (vdigits == 0)
             {
               do
-                RANDOM_BITS (v);
+                v = random_bits (v);
               while (unfair_min <= v);
 
               vdigits = BASE_62_DIGITS;
diff --git a/modules/tempname b/modules/tempname
index d55f4ce1a..385c65a6e 100644
--- a/modules/tempname
+++ b/modules/tempname
@@ -9,14 +9,17 @@ m4/tempname.m4
 
 Depends-on:
 c99
+clock-time
 extensions
 fcntl-h
 getrandom
 libc-config
 lstat
 mkdir
+stdalign
 stdint
 sys_stat
+time
 
 configure.ac:
 gl_FUNC_GEN_TEMPNAME
-- 
2.25.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]