Date: Wed, 4 Jul 2012 19:51:25 +0000 (UTC) From: Pawel Jakub Dawidek <pjd@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r238118 - head/lib/libc/gen Message-ID: <201207041951.q64JpPXu029310@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: pjd Date: Wed Jul 4 19:51:25 2012 New Revision: 238118 URL: http://svn.freebsd.org/changeset/base/238118 Log: Prefer sysctl to open/read/close for obtaining random data. This method is more sandbox-friendly and also should be faster as only one syscall is needed instead of three. In case of an error fall back to the old method. Reviewed by: simon, gleb MFC after: 2 weeks Modified: head/lib/libc/gen/arc4random.c Modified: head/lib/libc/gen/arc4random.c ============================================================================== --- head/lib/libc/gen/arc4random.c Wed Jul 4 17:59:26 2012 (r238117) +++ head/lib/libc/gen/arc4random.c Wed Jul 4 19:51:25 2012 (r238118) @@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$"); #include <unistd.h> #include <sys/types.h> #include <sys/param.h> +#include <sys/sysctl.h> #include <sys/time.h> #include <pthread.h> @@ -78,6 +79,9 @@ static struct arc4_stream rs; static pid_t arc4_stir_pid; static int arc4_count; +extern int __sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, + void *newp, size_t newlen); + static inline u_int8_t arc4_getbyte(void); static void arc4_stir(void); @@ -109,6 +113,28 @@ arc4_addrandom(u_char *dat, int datlen) rs.j = rs.i; } +static size_t +arc4_sysctl(u_char *buf, size_t size) +{ + int mib[2]; + size_t len, done; + + mib[0] = CTL_KERN; + mib[1] = KERN_ARND; + done = 0; + + do { + len = size; + if (__sysctl(mib, 2, buf, &len, NULL, 0) == -1) + return (done); + done += len; + buf += len; + size -= len; + } while (size > 0); + + return (done); +} + static void arc4_stir(void) { @@ -123,12 +149,16 @@ arc4_stir(void) arc4_init(); rs_initialized = 1; } - fd = _open(RANDOMDEV, O_RDONLY, 0); done = 0; - if (fd >= 0) { - if (_read(fd, &rdat, KEYSIZE) == KEYSIZE) - done = 1; - (void)_close(fd); + if (arc4_sysctl((u_char *)&rdat, KEYSIZE) == KEYSIZE) + done = 1; + if (!done) { + fd = _open(RANDOMDEV, O_RDONLY, 0); + if (fd >= 0) { + if (_read(fd, &rdat, KEYSIZE) == KEYSIZE) + done = 1; + (void)_close(fd); + } } if (!done) { (void)gettimeofday(&rdat.tv, NULL);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201207041951.q64JpPXu029310>