From 12a6865090ad2f88c671256c53a8fed4d5424424 Mon Sep 17 00:00:00 2001 From: Xin LI Date: Tue, 2 Apr 2013 23:41:20 +0000 Subject: [PATCH] Replace access to /dev/random with the kernel pseudo-random number source sysctl(KERN_ARND) and remove the fallback code. Obtained from: OpenBSD Reviewed by: secteam MFC after: 1 month --- lib/libc/stdlib/rand.3 | 6 ++---- lib/libc/stdlib/rand.c | 29 ++++++++++----------------- lib/libc/stdlib/random.3 | 6 +++--- lib/libc/stdlib/random.c | 42 ++++++++++++++-------------------------- 4 files changed, 30 insertions(+), 53 deletions(-) diff --git a/lib/libc/stdlib/rand.3 b/lib/libc/stdlib/rand.3 index 390a40bfeced..bf50e3d87e72 100644 --- a/lib/libc/stdlib/rand.3 +++ b/lib/libc/stdlib/rand.3 @@ -32,7 +32,7 @@ .\" @(#)rand.3 8.1 (Berkeley) 6/4/93 .\" $FreeBSD$ .\" -.Dd September 4, 2012 +.Dd April 2, 2013 .Dt RAND 3 .Os .Sh NAME @@ -91,9 +91,7 @@ seeded with a value of 1. .Pp The .Fn sranddev -function initializes a seed using the -.Xr random 4 -random number device which returns good random numbers. +function initializes a seed using pseudo-random numbers obtained from the kernel. .Pp The .Fn rand_r diff --git a/lib/libc/stdlib/rand.c b/lib/libc/stdlib/rand.c index 704181890bb7..0cbd94883125 100644 --- a/lib/libc/stdlib/rand.c +++ b/lib/libc/stdlib/rand.c @@ -36,11 +36,10 @@ static char sccsid[] = "@(#)rand.c 8.1 (Berkeley) 6/14/93"; __FBSDID("$FreeBSD$"); #include "namespace.h" -#include /* for sranddev() */ +#include +#include #include -#include /* for sranddev() */ #include -#include /* for sranddev() */ #include "un-namespace.h" #ifdef TEST @@ -112,28 +111,20 @@ u_int seed; * sranddev: * * Many programs choose the seed value in a totally predictable manner. - * This often causes problems. We seed the generator using the much more - * secure random(4) interface. + * This often causes problems. We seed the generator using pseudo-random + * data from the kernel. */ void sranddev() { - int fd, done; + int mib[2]; + size_t len; - done = 0; - fd = _open("/dev/random", O_RDONLY | O_CLOEXEC, 0); - if (fd >= 0) { - if (_read(fd, (void *) &next, sizeof(next)) == sizeof(next)) - done = 1; - _close(fd); - } + len = sizeof(next); - if (!done) { - struct timeval tv; - - gettimeofday(&tv, NULL); - srand((getpid() << 16) ^ tv.tv_sec ^ tv.tv_usec); - } + mib[0] = CTL_KERN; + mib[1] = KERN_ARND; + sysctl(mib, 2, (void *)&next, &len, NULL, 0); } diff --git a/lib/libc/stdlib/random.3 b/lib/libc/stdlib/random.3 index 4817440ec0b2..a1e585bbd24a 100644 --- a/lib/libc/stdlib/random.3 +++ b/lib/libc/stdlib/random.3 @@ -28,7 +28,7 @@ .\" @(#)random.3 8.1 (Berkeley) 6/4/93 .\" $FreeBSD$ .\" -.Dd September 4, 2012 +.Dd April 2, 2013 .Dt RANDOM 3 .Os .Sh NAME @@ -106,8 +106,8 @@ as the seed. .Pp The .Fn srandomdev -routine initializes a state array using data from -.Xr random 4 . +routine initializes a state array using +pseudo-random numbers obtained from the kernel. Note that this particular seeding procedure can generate states which are impossible to reproduce by calling diff --git a/lib/libc/stdlib/random.c b/lib/libc/stdlib/random.c index a3c054e5ba0e..4c88ecbbc881 100644 --- a/lib/libc/stdlib/random.c +++ b/lib/libc/stdlib/random.c @@ -34,12 +34,11 @@ static char sccsid[] = "@(#)random.c 8.2 (Berkeley) 5/19/95"; __FBSDID("$FreeBSD$"); #include "namespace.h" -#include /* for srandomdev() */ -#include /* for srandomdev() */ +#include +#include #include #include #include -#include /* for srandomdev() */ #include "un-namespace.h" /* @@ -284,39 +283,28 @@ srandom(unsigned long x) * srandomdev: * * Many programs choose the seed value in a totally predictable manner. - * This often causes problems. We seed the generator using the much more - * secure random(4) interface. Note that this particular seeding - * procedure can generate states which are impossible to reproduce by - * calling srandom() with any value, since the succeeding terms in the - * state buffer are no longer derived from the LC algorithm applied to - * a fixed seed. + * This often causes problems. We seed the generator using pseudo-random + * data from the kernel. + * + * Note that this particular seeding procedure can generate states + * which are impossible to reproduce by calling srandom() with any + * value, since the succeeding terms in the state buffer are no longer + * derived from the LC algorithm applied to a fixed seed. */ void srandomdev(void) { - int fd, done; + int mib[2]; size_t len; if (rand_type == TYPE_0) - len = sizeof state[0]; + len = sizeof(state[0]); else - len = rand_deg * sizeof state[0]; + len = rand_deg * sizeof(state[0]); - done = 0; - fd = _open("/dev/random", O_RDONLY | O_CLOEXEC, 0); - if (fd >= 0) { - if (_read(fd, (void *) state, len) == (ssize_t) len) - done = 1; - _close(fd); - } - - if (!done) { - struct timeval tv; - - gettimeofday(&tv, NULL); - srandom((getpid() << 16) ^ tv.tv_sec ^ tv.tv_usec); - return; - } + mib[0] = CTL_KERN; + mib[1] = KERN_ARND; + sysctl(mib, 2, state, &len, NULL, 0); if (rand_type != TYPE_0) { fptr = &state[rand_sep];