From owner-freebsd-bugs@FreeBSD.ORG Mon Feb 23 13:50:11 2004 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id BD49A16A4CE for ; Mon, 23 Feb 2004 13:50:11 -0800 (PST) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id A01B443D2D for ; Mon, 23 Feb 2004 13:50:11 -0800 (PST) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) i1NLoBbv068500 for ; Mon, 23 Feb 2004 13:50:11 -0800 (PST) (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.12.10/8.12.10/Submit) id i1NLoBrD068499; Mon, 23 Feb 2004 13:50:11 -0800 (PST) (envelope-from gnats) Resent-Date: Mon, 23 Feb 2004 13:50:11 -0800 (PST) Resent-Message-Id: <200402232150.i1NLoBrD068499@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, "Christian S.J. Peron" Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 2466C16A4CE; Mon, 23 Feb 2004 13:45:07 -0800 (PST) Received: from h24-77-20-99.wp.shawcable.net (h24-77-20-99.wp.shawcable.net [24.77.20.99]) by mx1.FreeBSD.org (Postfix) with ESMTP id 50B5643D1D; Mon, 23 Feb 2004 13:45:06 -0800 (PST) (envelope-from modulus@h24-77-20-99.wp.shawcable.net) Received: from h24-77-20-99.wp.shawcable.net (localhost [127.0.0.1]) i1NLmEeO025285; Mon, 23 Feb 2004 21:48:15 GMT (envelope-from modulus@h24-77-20-99.wp.shawcable.net) Received: (from root@localhost)i1NLmE1I025284; Mon, 23 Feb 2004 21:48:14 GMT (envelope-from modulus) Message-Id: <200402232148.i1NLmE1I025284@h24-77-20-99.wp.shawcable.net> Date: Mon, 23 Feb 2004 21:48:14 GMT From: "Christian S.J. Peron" To: FreeBSD-gnats-submit@FreeBSD.org X-Send-Pr-Version: 3.113 cc: green@FreeBSD.org Subject: bin/63287: [patch] patch to make libc arc4random reentrant X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list Reply-To: "Christian S.J. Peron" List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 23 Feb 2004 21:50:11 -0000 >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 #include #include +#include + +#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: