[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