[PATCH] elf: Do not scrub AT_RANDOM to a constant when reseeding fails (BZ 34197)

Adhemerval Zanella adhemerval.zanella@linaro.org
Tue Jun 16 19:16:13 GMT 2026


_dl_reseed_random zeroed the AT_RANDOM bytes before refilling them with
getrandom (GRND_NONBLOCK).  That call is best-effort and can write nothing
(e.g. before the kernel entropy pool is initialized early at boot), leaving
the 16 bytes as a constant zero.

Since the value is exposed through getauxval (AT_RANDOM), this traded a
potential guard leak for a guaranteed predictable value.

Drop the memset and overwrite the bytes in place instead.  The generic
version now just drops the pointer (it is not used anywhere).

Checked on x86_64-linux-gnu and i686-linux-gnu.
---
 sysdeps/generic/dl-reseed-random.h         |  8 +++-----
 sysdeps/unix/sysv/linux/dl-reseed-random.h | 17 +++++++++--------
 2 files changed, 12 insertions(+), 13 deletions(-)

diff --git a/sysdeps/generic/dl-reseed-random.h b/sysdeps/generic/dl-reseed-random.h
index 7e1a3c3be21..b55bdb909cc 100644
--- a/sysdeps/generic/dl-reseed-random.h
+++ b/sysdeps/generic/dl-reseed-random.h
@@ -19,15 +19,13 @@
 #ifndef _DL_RESEED_RANDOM_H
 #define _DL_RESEED_RANDOM_H
 
-#include <string.h>
+#include <stddef.h>
 
+/* Leave the kernel-provided bytes untouched rather than scrubbing them to a
+   predictable constant, the value is exposed through getauxval (AT_RANDOM). */
 static inline void __attribute__ ((always_inline))
 _dl_reseed_random (void **dl_random)
 {
-  if (*dl_random == NULL)
-    return;
-  memset (*dl_random, '\0', 16);
-  __asm__ __volatile__ ("" : : "r" (*dl_random) : "memory");
   *dl_random = NULL;
 }
 
diff --git a/sysdeps/unix/sysv/linux/dl-reseed-random.h b/sysdeps/unix/sysv/linux/dl-reseed-random.h
index b0ceb5cc659..cf0a898b993 100644
--- a/sysdeps/unix/sysv/linux/dl-reseed-random.h
+++ b/sysdeps/unix/sysv/linux/dl-reseed-random.h
@@ -19,23 +19,24 @@
 #ifndef _DL_RESEED_RANDOM_H
 #define _DL_RESEED_RANDOM_H
 
-#include <string.h>
 #include <not-cancel.h>
 #include <sys/random.h>
 
 /* The stack and pointer guards have been derived from the 16 AT_RANDOM
-   bytes pointed to by DL_RANDOM.  Scrub them first, so the guards cannot be
-   recovered even if the refill below fails, then refill them with fresh
-   entropy unrelated to the guards so that getauxval (AT_RANDOM) keeps
-   returning random bytes.  */
+   bytes pointed to by DL_RANDOM.  Overwrite them in place with fresh entropy
+   unrelated to the guards, so the value returned by getauxval (AT_RANDOM) no
+   longer reveals them while still being random.
+
+   This is best-effort and must not perturb process startup.  The getrandom
+   might not provide all the requested entropy, and leaving the original bytes
+   is deliberate: AT_RANDOM is exposed through getauxval, and a potential
+   leak of the guards is preferable to scrubbing the value to a predictable
+   constant.  */
 static inline void __attribute__ ((always_inline))
 _dl_reseed_random (void **dl_random)
 {
   if (*dl_random == NULL)
     return;
-  memset (*dl_random, '\0', 16);
-  __asm__ __volatile__ ("" : : "r" (*dl_random) : "memory");
-
   __getrandom_nocancel_nostatus_direct (*dl_random, 16, GRND_NONBLOCK);
   *dl_random = NULL;
 }
-- 
2.43.0



More information about the Libc-alpha mailing list