summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKurt Miller <kurt@cvs.openbsd.org>2008-01-01 00:43:40 +0000
committerKurt Miller <kurt@cvs.openbsd.org>2008-01-01 00:43:40 +0000
commit0c67ab8bf7edbef019be3f16d6fecf3415f936b8 (patch)
tree0962e1797400e9c942f430c5e9f445d72fb5452b
parenta2bf00b0dbd8e50cb2c798d07003e3a20aa2d32c (diff)
- make arc4random*() functions thread safe. Use a custom spinlock function
instead of the generic pthread macros since free(3) uses __arc4_getbyte() when freeing small sized allocations and the generic pthread macros call malloc(3). - eliminate passing pointers to a static variable with global scope (rs) for additional code clarity and reduction. - shlib minor bumps for libc and libpthread due to new functions. From andreas@ with some bits from me. okay tedu@ marc@ w/some spot checking from millert@
-rw-r--r--lib/libc/crypt/arc4random.c97
-rw-r--r--lib/libc/include/thread_private.h14
-rw-r--r--lib/libc/shlib_version2
-rw-r--r--lib/libc/thread/unithread_malloc_lock.c20
-rw-r--r--lib/libpthread/shlib_version2
-rw-r--r--lib/libpthread/thread/thread_malloc_lock.c15
-rw-r--r--lib/libpthread/uthread/uthread_init.c4
-rw-r--r--lib/librthread/rthread_libc.c19
8 files changed, 125 insertions, 48 deletions
diff --git a/lib/libc/crypt/arc4random.c b/lib/libc/crypt/arc4random.c
index 35d79530022..8604548f3fc 100644
--- a/lib/libc/crypt/arc4random.c
+++ b/lib/libc/crypt/arc4random.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: arc4random.c,v 1.16 2007/02/12 19:58:47 otto Exp $ */
+/* $OpenBSD: arc4random.c,v 1.17 2008/01/01 00:43:39 kurt Exp $ */
/*
* Copyright (c) 1996, David Mazieres <dm@uun.org>
@@ -40,6 +40,7 @@
#include <sys/param.h>
#include <sys/time.h>
#include <sys/sysctl.h>
+#include "thread_private.h"
#ifdef __GNUC__
#define inline __inline
@@ -58,43 +59,48 @@ static struct arc4_stream rs;
static pid_t arc4_stir_pid;
static int arc4_count;
-static inline u_int8_t arc4_getbyte(struct arc4_stream *);
+static inline u_int8_t arc4_getbyte(void);
static inline void
-arc4_init(struct arc4_stream *as)
+arc4_init(void)
{
int n;
for (n = 0; n < 256; n++)
- as->s[n] = n;
- as->i = 0;
- as->j = 0;
+ rs.s[n] = n;
+ rs.i = 0;
+ rs.j = 0;
}
static inline void
-arc4_addrandom(struct arc4_stream *as, u_char *dat, int datlen)
+arc4_addrandom(u_char *dat, int datlen)
{
int n;
u_int8_t si;
- as->i--;
+ rs.i--;
for (n = 0; n < 256; n++) {
- as->i = (as->i + 1);
- si = as->s[as->i];
- as->j = (as->j + si + dat[n % datlen]);
- as->s[as->i] = as->s[as->j];
- as->s[as->j] = si;
+ rs.i = (rs.i + 1);
+ si = rs.s[rs.i];
+ rs.j = (rs.j + si + dat[n % datlen]);
+ rs.s[rs.i] = rs.s[rs.j];
+ rs.s[rs.j] = si;
}
- as->j = as->i;
+ rs.j = rs.i;
}
static void
-arc4_stir(struct arc4_stream *as)
+arc4_stir(void)
{
int i, mib[2];
size_t len;
u_char rnd[128];
+ if (!rs_initialized) {
+ arc4_init();
+ rs_initialized = 1;
+ }
+
mib[0] = CTL_KERN;
mib[1] = KERN_ARND;
@@ -102,75 +108,84 @@ arc4_stir(struct arc4_stream *as)
sysctl(mib, 2, rnd, &len, NULL, 0);
arc4_stir_pid = getpid();
- arc4_addrandom(as, rnd, sizeof(rnd));
+ arc4_addrandom(rnd, sizeof(rnd));
/*
* Discard early keystream, as per recommendations in:
* http://www.wisdom.weizmann.ac.il/~itsik/RC4/Papers/Rc4_ksa.ps
*/
for (i = 0; i < 256; i++)
- (void)arc4_getbyte(as);
+ (void)arc4_getbyte();
arc4_count = 1600000;
}
static inline u_int8_t
-arc4_getbyte(struct arc4_stream *as)
+arc4_getbyte(void)
{
u_int8_t si, sj;
- as->i = (as->i + 1);
- si = as->s[as->i];
- as->j = (as->j + si);
- sj = as->s[as->j];
- as->s[as->i] = sj;
- as->s[as->j] = si;
- return (as->s[(si + sj) & 0xff]);
+ rs.i = (rs.i + 1);
+ si = rs.s[rs.i];
+ rs.j = (rs.j + si);
+ sj = rs.s[rs.j];
+ rs.s[rs.i] = sj;
+ rs.s[rs.j] = si;
+ return (rs.s[(si + sj) & 0xff]);
}
u_int8_t
__arc4_getbyte(void)
{
+ u_int8_t val;
+
+ _ARC4_LOCK();
if (--arc4_count == 0 || !rs_initialized)
- arc4random_stir();
- return arc4_getbyte(&rs);
+ arc4_stir();
+ val = arc4_getbyte();
+ _ARC4_UNLOCK();
+ return val;
}
static inline u_int32_t
-arc4_getword(struct arc4_stream *as)
+arc4_getword(void)
{
u_int32_t val;
- val = arc4_getbyte(as) << 24;
- val |= arc4_getbyte(as) << 16;
- val |= arc4_getbyte(as) << 8;
- val |= arc4_getbyte(as);
+ val = arc4_getbyte() << 24;
+ val |= arc4_getbyte() << 16;
+ val |= arc4_getbyte() << 8;
+ val |= arc4_getbyte();
return val;
}
void
arc4random_stir(void)
{
- if (!rs_initialized) {
- arc4_init(&rs);
- rs_initialized = 1;
- }
- arc4_stir(&rs);
+ _ARC4_LOCK();
+ arc4_stir();
+ _ARC4_UNLOCK();
}
void
arc4random_addrandom(u_char *dat, int datlen)
{
+ _ARC4_LOCK();
if (!rs_initialized)
- arc4random_stir();
- arc4_addrandom(&rs, dat, datlen);
+ arc4_stir();
+ arc4_addrandom(dat, datlen);
+ _ARC4_UNLOCK();
}
u_int32_t
arc4random(void)
{
+ u_int32_t val;
+ _ARC4_LOCK();
arc4_count -= 4;
if (arc4_count <= 0 || !rs_initialized || arc4_stir_pid != getpid())
- arc4random_stir();
- return arc4_getword(&rs);
+ arc4_stir();
+ val = arc4_getword();
+ _ARC4_UNLOCK();
+ return val;
}
#if 0
diff --git a/lib/libc/include/thread_private.h b/lib/libc/include/thread_private.h
index 146f0b0a015..f55880f7bae 100644
--- a/lib/libc/include/thread_private.h
+++ b/lib/libc/include/thread_private.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: thread_private.h,v 1.21 2007/11/19 02:54:19 kurt Exp $ */
+/* $OpenBSD: thread_private.h,v 1.22 2008/01/01 00:43:39 kurt Exp $ */
/* PUBLIC DOMAIN: No Rights Reserved. Marco S Hyman <marc@snafu.org> */
@@ -150,4 +150,16 @@ void _thread_atexit_unlock(void);
_thread_atexit_unlock();\
} while (0)
+void _thread_arc4_lock(void);
+void _thread_arc4_unlock(void);
+
+#define _ARC4_LOCK() do { \
+ if (__isthreaded) \
+ _thread_arc4_lock(); \
+ } while (0)
+#define _ARC4_UNLOCK() do { \
+ if (__isthreaded) \
+ _thread_arc4_unlock();\
+ } while (0)
+
#endif /* _THREAD_PRIVATE_H_ */
diff --git a/lib/libc/shlib_version b/lib/libc/shlib_version
index d5194cd8c2f..3c07d167bfa 100644
--- a/lib/libc/shlib_version
+++ b/lib/libc/shlib_version
@@ -1,4 +1,4 @@
major=42
-minor=0
+minor=1
# note: If changes were made to include/thread_private.h or if system
# calls were added/changed then libpthread must also be updated.
diff --git a/lib/libc/thread/unithread_malloc_lock.c b/lib/libc/thread/unithread_malloc_lock.c
index f7231915d6f..ca5081ba780 100644
--- a/lib/libc/thread/unithread_malloc_lock.c
+++ b/lib/libc/thread/unithread_malloc_lock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: unithread_malloc_lock.c,v 1.6 2006/02/22 07:16:32 otto Exp $ */
+/* $OpenBSD: unithread_malloc_lock.c,v 1.7 2008/01/01 00:43:39 kurt Exp $ */
#include <sys/time.h>
#include "thread_private.h"
@@ -17,6 +17,12 @@ WEAK_PROTOTYPE(_thread_atexit_unlock);
WEAK_ALIAS(_thread_atexit_lock);
WEAK_ALIAS(_thread_atexit_unlock);
+WEAK_PROTOTYPE(_thread_arc4_lock);
+WEAK_PROTOTYPE(_thread_arc4_unlock);
+
+WEAK_ALIAS(_thread_arc4_lock);
+WEAK_ALIAS(_thread_arc4_unlock);
+
void
WEAK_NAME(_thread_malloc_lock)(void)
{
@@ -46,3 +52,15 @@ WEAK_NAME(_thread_atexit_unlock)(void)
{
return;
}
+
+void
+WEAK_NAME(_thread_arc4_lock)(void)
+{
+ return;
+}
+
+void
+WEAK_NAME(_thread_arc4_unlock)(void)
+{
+ return;
+}
diff --git a/lib/libpthread/shlib_version b/lib/libpthread/shlib_version
index d0f0988b418..00604e64e7d 100644
--- a/lib/libpthread/shlib_version
+++ b/lib/libpthread/shlib_version
@@ -1,2 +1,2 @@
major=8
-minor=0
+minor=1
diff --git a/lib/libpthread/thread/thread_malloc_lock.c b/lib/libpthread/thread/thread_malloc_lock.c
index 6e8b96bb656..6deebb53f66 100644
--- a/lib/libpthread/thread/thread_malloc_lock.c
+++ b/lib/libpthread/thread/thread_malloc_lock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: thread_malloc_lock.c,v 1.5 2006/02/22 07:16:32 otto Exp $ */
+/* $OpenBSD: thread_malloc_lock.c,v 1.6 2008/01/01 00:43:39 kurt Exp $ */
/* Public Domain <marc@snafu.org> */
#include <pthread.h>
@@ -6,6 +6,7 @@
static spinlock_t malloc_lock = _SPINLOCK_INITIALIZER;
static spinlock_t atexit_lock = _SPINLOCK_INITIALIZER;
+static spinlock_t arc4_lock = _SPINLOCK_INITIALIZER;
void
_thread_malloc_lock()
@@ -35,3 +36,15 @@ _thread_atexit_unlock()
{
_SPINUNLOCK(&atexit_lock);
}
+
+void
+_thread_arc4_lock()
+{
+ _SPINLOCK(&arc4_lock);
+}
+
+void
+_thread_arc4_unlock()
+{
+ _SPINUNLOCK(&arc4_lock);
+}
diff --git a/lib/libpthread/uthread/uthread_init.c b/lib/libpthread/uthread/uthread_init.c
index d48e1173566..36559a5ae34 100644
--- a/lib/libpthread/uthread/uthread_init.c
+++ b/lib/libpthread/uthread/uthread_init.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_init.c,v 1.40 2007/07/20 22:34:40 kettenis Exp $ */
+/* $OpenBSD: uthread_init.c,v 1.41 2008/01/01 00:43:39 kurt Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -135,6 +135,8 @@ static void *references[] = {
&_thread_malloc_unlock,
&_thread_atexit_lock,
&_thread_atexit_unlock,
+ &_thread_arc4_lock,
+ &_thread_arc4_unlock,
&_thread_tag_lock,
&_thread_tag_unlock,
&_thread_tag_storage,
diff --git a/lib/librthread/rthread_libc.c b/lib/librthread/rthread_libc.c
index bf3c057d874..da0d92f8da5 100644
--- a/lib/librthread/rthread_libc.c
+++ b/lib/librthread/rthread_libc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rthread_libc.c,v 1.4 2007/06/05 18:11:49 kurt Exp $ */
+/* $OpenBSD: rthread_libc.c,v 1.5 2008/01/01 00:43:39 kurt Exp $ */
/* $snafu: libc_tag.c,v 1.4 2004/11/30 07:00:06 marc Exp $ */
/* PUBLIC DOMAIN: No Rights Reserved. Marco S Hyman <marc@snafu.org> */
@@ -175,6 +175,23 @@ _thread_malloc_init(void)
{
}
+/*
+ * arc4random lock
+ */
+static _spinlock_lock_t arc4_lock = _SPINLOCK_UNLOCKED;
+
+void
+_thread_arc4_lock(void)
+{
+ _spinlock(&arc4_lock);
+}
+
+void
+_thread_arc4_unlock(void)
+{
+ _spinunlock(&arc4_lock);
+}
+
#if 0
/*
* miscellaneous libc exported symbols we want to override