[glibc] elf: Do not scrub AT_RANDOM to a constant when reseeding fails (BZ 34197)
Adhemerval Zanella via Glibc-cvs <[email protected]> Wed, 17 Jun 2026 13:02:51 +0000 (GMT)
| Newsgroups | gmane.comp.lib.glibc.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=242a1f4b0f8d72948ee14a33c2dd5d0c361b6d73 commit 242a1f4b0f8d72948ee14a33c2dd5d0c361b6d73 Author: Adhemerval Zanella <[email protected]> Date: Tue Jun 16 16:10:01 2026 -0300 elf: Do not scrub AT_RANDOM to a constant when reseeding fails (BZ 34197) _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. Reviewed-by: Florian Weimer <[email protected]> Diff: --- 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 7e1a3c3be2..b55bdb909c 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 b0ceb5cc65..cf0a898b99 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; }