On Thu, 24 Oct 2019, Ossama Othman wrote:
The random() PRNG is used as a fallback in case of getrandom()
syscall
failure. However, the PRNG was not seeded prior to initial use,
resulting in the same predictable sequence of numbers being generated.
Explicitly seed the PRNG on initial use with random data retrieved
from the ELF binary loader to decrease predictability.
---
ell/random.c | 19 ++++++++++++++++++-
1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/ell/random.c b/ell/random.c
index 0b5b09e..99aa06e 100644
--- a/ell/random.c
+++ b/ell/random.c
@@ -28,6 +28,8 @@
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
+#include <time.h>
+#include <sys/auxv.h>
#include <sys/syscall.h>
#include "random.h"
@@ -95,11 +97,26 @@ LIB_EXPORT uint32_t l_getrandom_uint32(void)
{
int ret;
uint32_t u;
+ static unsigned int seed = 0; /* For fallback PRNG. */
ret = getrandom(&u, sizeof(u), GRND_NONBLOCK);
if (ret == sizeof(u))
return u;
- return random() * RAND_MAX + random();
+ if (seed == 0) {
+ /*
+ * Seed the fallback PRNG below with the
+ * process-specific random data supplied by the
+ * kernel, skipping the canary in the first half.
+ */
+ unsigned long addr =
+ getauxval(AT_RANDOM) + sizeof(void *);
getauxval is a nonstandard glibc extension, so there needs to be a way to
fall back to something else (or skip this) for other C libraries.
+
+ seed = *((unsigned long *) addr) ^ time(NULL);
+
+ srandom(seed);
+ }
+
+ return random() * RAND_MAX + random();
}
--
2.20.1
_______________________________________________
ell mailing list -- ell(a)lists.01.org
To unsubscribe send an email to ell-leave(a)lists.01.org
--
Mat Martineau
Intel