aboutsummaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorBodo Möller <bodo@openssl.org>2001-07-25 17:17:24 +0000
committerBodo Möller <bodo@openssl.org>2001-07-25 17:17:24 +0000
commitdaba492c3a461bbcc0df69d609124936a19205f6 (patch)
tree81307c480eb35de93be0718534440e36a9d6ecf1 /crypto
parent24cff6ced5813a4d4014ed86828fba4e326d5868 (diff)
downloadopenssl-daba492c3a461bbcc0df69d609124936a19205f6.tar.gz
md_rand.c thread safety
Diffstat (limited to 'crypto')
-rw-r--r--crypto/cryptlib.c3
-rw-r--r--crypto/crypto.h27
-rw-r--r--crypto/rand/md_rand.c23
3 files changed, 37 insertions, 16 deletions
diff --git a/crypto/cryptlib.c b/crypto/cryptlib.c
index b733abafee..be83f5617f 100644
--- a/crypto/cryptlib.c
+++ b/crypto/cryptlib.c
@@ -90,6 +90,7 @@ static const char* lock_names[CRYPTO_NUM_LOCKS] =
"ssl_sess_cert",
"ssl",
"rand",
+ "rand2",
"debug_malloc",
"BIO",
"gethostbyname",
@@ -102,7 +103,7 @@ static const char* lock_names[CRYPTO_NUM_LOCKS] =
"dynlock",
"engine",
"ui",
-#if CRYPTO_NUM_LOCKS != 30
+#if CRYPTO_NUM_LOCKS != 31
# error "Inconsistency between crypto.h and cryptlib.c"
#endif
};
diff --git a/crypto/crypto.h b/crypto/crypto.h
index c54f471290..53b85238c0 100644
--- a/crypto/crypto.h
+++ b/crypto/crypto.h
@@ -113,19 +113,20 @@ extern "C" {
#define CRYPTO_LOCK_SSL_SESS_CERT 15
#define CRYPTO_LOCK_SSL 16
#define CRYPTO_LOCK_RAND 17
-#define CRYPTO_LOCK_MALLOC 18
-#define CRYPTO_LOCK_BIO 19
-#define CRYPTO_LOCK_GETHOSTBYNAME 20
-#define CRYPTO_LOCK_GETSERVBYNAME 21
-#define CRYPTO_LOCK_READDIR 22
-#define CRYPTO_LOCK_RSA_BLINDING 23
-#define CRYPTO_LOCK_DH 24
-#define CRYPTO_LOCK_MALLOC2 25
-#define CRYPTO_LOCK_DSO 26
-#define CRYPTO_LOCK_DYNLOCK 27
-#define CRYPTO_LOCK_ENGINE 28
-#define CRYPTO_LOCK_UI 29
-#define CRYPTO_NUM_LOCKS 30
+#define CRYPTO_LOCK_RAND2 18
+#define CRYPTO_LOCK_MALLOC 19
+#define CRYPTO_LOCK_BIO 20
+#define CRYPTO_LOCK_GETHOSTBYNAME 21
+#define CRYPTO_LOCK_GETSERVBYNAME 22
+#define CRYPTO_LOCK_READDIR 23
+#define CRYPTO_LOCK_RSA_BLINDING 24
+#define CRYPTO_LOCK_DH 25
+#define CRYPTO_LOCK_MALLOC2 26
+#define CRYPTO_LOCK_DSO 27
+#define CRYPTO_LOCK_DYNLOCK 28
+#define CRYPTO_LOCK_ENGINE 29
+#define CRYPTO_LOCK_UI 30
+#define CRYPTO_NUM_LOCKS 31
#define CRYPTO_LOCK 1
#define CRYPTO_UNLOCK 2
diff --git a/crypto/rand/md_rand.c b/crypto/rand/md_rand.c
index 2a56ace4ee..6d7f37e15e 100644
--- a/crypto/rand/md_rand.c
+++ b/crypto/rand/md_rand.c
@@ -144,6 +144,7 @@ static int initialized=0;
static unsigned int crypto_lock_rand = 0; /* may be set only when a thread
* holds CRYPTO_LOCK_RAND
* (to prevent double locking) */
+/* access to lockin_thread is synchronized by CRYPTO_LOCK_RAND2 */
static unsigned long locking_thread = 0; /* valid iff crypto_lock_rand is set */
@@ -210,7 +211,14 @@ static void ssleay_rand_add(const void *buf, int num, double add)
*/
/* check if we already have the lock */
- do_not_lock = crypto_lock_rand && (locking_thread == CRYPTO_thread_id());
+ if (crypto_lock_rand)
+ {
+ CRYPTO_r_lock(CRYPTO_LOCK_RAND2);
+ do_not_lock = (locking_thread == CRYPTO_thread_id());
+ CRYPTO_r_unlock(CRYPTO_LOCK_RAND2);
+ }
+ else
+ do_not_lock = 0;
if (!do_not_lock) CRYPTO_w_lock(CRYPTO_LOCK_RAND);
st_idx=state_index;
@@ -361,7 +369,9 @@ static int ssleay_rand_bytes(unsigned char *buf, int num)
CRYPTO_w_lock(CRYPTO_LOCK_RAND);
/* prevent ssleay_rand_bytes() from trying to obtain the lock again */
+ CRYPTO_w_lock(CRYPTO_LOCK_RAND2);
locking_thread = CRYPTO_thread_id();
+ CRYPTO_w_unlock(CRYPTO_LOCK_RAND2);
crypto_lock_rand = 1;
if (!initialized)
@@ -520,14 +530,23 @@ static int ssleay_rand_status(void)
/* check if we already have the lock
* (could happen if a RAND_poll() implementation calls RAND_status()) */
- do_not_lock = crypto_lock_rand && (locking_thread == CRYPTO_thread_id());
+ if (crypto_lock_rand)
+ {
+ CRYPTO_r_lock(CRYPTO_LOCK_RAND2);
+ do_not_lock = (locking_thread == CRYPTO_thread_id());
+ CRYPTO_r_unlock(CRYPTO_LOCK_RAND2);
+ }
+ else
+ do_not_lock = 0;
if (!do_not_lock)
{
CRYPTO_w_lock(CRYPTO_LOCK_RAND);
/* prevent ssleay_rand_bytes() from trying to obtain the lock again */
+ CRYPTO_w_lock(CRYPTO_LOCK_RAND2);
locking_thread = CRYPTO_thread_id();
+ CRYPTO_w_unlock(CRYPTO_LOCK_RAND2);
crypto_lock_rand = 1;
}