Date: Mon, 23 Feb 2004 21:48:14 GMT From: "Christian S.J. Peron" <maneo@bsdpro.com> To: FreeBSD-gnats-submit@FreeBSD.org Cc: green@FreeBSD.org Subject: bin/63287: [patch] patch to make libc arc4random reentrant Message-ID: <200402232148.i1NLmE1I025284@h24-77-20-99.wp.shawcable.net> Resent-Message-ID: <200402232150.i1NLoBrD068499@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 63287 >Category: bin >Synopsis: [patch] patch to make libc arc4random reentrant >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Mon Feb 23 13:50:11 PST 2004 >Closed-Date: >Last-Modified: >Originator: Christian S.J. Peron >Release: FreeBSD 5.2-CURRENT i386 >Organization: >Environment: System: FreeBSD movl 5.2-CURRENT FreeBSD 5.2-CURRENT #8: Mon Feb 2 22:04:49 GMT 2004 modulus@movl:/usr/src/sys/i386/compile/ROUTER i386 >Description: Manipulation and permutation of S-boxes in the arc4random PRNG is susceptible to data races during multithreaded operation. I have enclosed a patch which serializes S-box manipulation. >How-To-Repeat: N/A >Fix: --- lib/libc/gen/arc4random.c.orig Mon Feb 23 20:15:57 2004 +++ lib/libc/gen/arc4random.c Mon Feb 23 21:05:12 2004 @@ -34,6 +34,9 @@ #include <stdlib.h> #include <fcntl.h> #include <unistd.h> +#include <pthread.h> + +#include "libc_private.h" #include "un-namespace.h" struct arc4_stream { @@ -42,10 +45,27 @@ u_int8_t s[256]; }; -static int rs_initialized; +static pthread_mutex_t arc4random_mtx = PTHREAD_MUTEX_INITIALIZER; + +#define RANDOMDEV "/dev/urandom" +#define THREAD_LOCK() \ + do { \ + if (__isthreaded) \ + _pthread_mutex_lock(&arc4random_mtx); \ + } while (0) + +#define THREAD_UNLOCK() \ + do { \ + if (__isthreaded) \ + _pthread_mutex_unlock(&arc4random_mtx); \ + } while (0) + static struct arc4_stream rs; +static int rs_initialized; +static int rs_stired; static inline u_int8_t arc4_getbyte(struct arc4_stream *); +static void arc4_stir(struct arc4_stream *); static inline void arc4_init(as) @@ -91,11 +111,11 @@ gettimeofday(&rdat.tv, NULL); rdat.pid = getpid(); - fd = _open("/dev/urandom", O_RDONLY, 0); + fd = _open(RANDOMDEV, O_RDONLY, 0); if (fd >= 0) { (void) _read(fd, rdat.rnd, sizeof(rdat.rnd)); _close(fd); - } + } /* fd < 0? Ah, what the heck. We'll just take whatever was on the * stack... */ @@ -142,14 +162,31 @@ return (val); } -void -arc4random_stir() +static void +arc4_check_init(void) { if (!rs_initialized) { arc4_init(&rs); rs_initialized = 1; } +} + +static void +arc4_check_stir(void) +{ + if (!rs_stired) { + arc4_stir(&rs); + rs_stired = 1; + } +} + +void +arc4random_stir() +{ + THREAD_LOCK(); + arc4_check_init(); arc4_stir(&rs); + THREAD_UNLOCK(); } void @@ -157,18 +194,25 @@ u_char *dat; int datlen; { - if (!rs_initialized) - arc4random_stir(); + THREAD_LOCK(); + arc4_check_init(); + arc4_check_stir(); arc4_addrandom(&rs, dat, datlen); + THREAD_UNLOCK(); } u_int32_t arc4random() { - if (!rs_initialized) - arc4random_stir(); + u_int32_t rnd; + + THREAD_LOCK(); + arc4_check_init(); + arc4_check_stir(); + rnd = arc4_getword(&rs); + THREAD_UNLOCK(); - return (arc4_getword(&rs)); + return (rnd); } #if 0 >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200402232148.i1NLmE1I025284>