summaryrefslogtreecommitdiffstats
path: root/crypto/mem.c
diff options
context:
space:
mode:
authorBodo Möller <bodo@openssl.org>1999-11-12 16:20:30 +0000
committerBodo Möller <bodo@openssl.org>1999-11-12 16:20:30 +0000
commit47d216940c454b8c6d229565051116c1108ddd2d (patch)
treeb4eb80d8b8006dea8180ae9b1ae58805fb254b06 /crypto/mem.c
parent01aad2c80a2e8ea8ccf1db34dce2b621253d454c (diff)
Avoid deadlock.
Diffstat (limited to 'crypto/mem.c')
-rw-r--r--crypto/mem.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/crypto/mem.c b/crypto/mem.c
index ddcc1113d5..1498672800 100644
--- a/crypto/mem.c
+++ b/crypto/mem.c
@@ -137,9 +137,23 @@ int CRYPTO_mem_ctrl(int mode)
if (mh_mode & CRYPTO_MEM_CHECK_ON)
{
mh_mode&= ~CRYPTO_MEM_CHECK_ENABLE;
- if (disabling_thread != CRYPTO_thread_id())
+ if (disabling_thread != CRYPTO_thread_id()) /* otherwise we already have the MALLOC2 lock */
{
+ /* Long-time lock CRYPTO_LOCK_MALLOC2 must not be claimed while
+ * we're holding CRYPTO_LOCK_MALLOC, or we'll deadlock if
+ * somebody else holds CRYPTO_LOCK_MALLOC2 (and cannot release it
+ * because we block entry to this function).
+ * Give them a chance, first, and then claim the locks in
+ * appropriate order (long-time lock first).
+ */
+ CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
+ /* Note that after we have waited for CRYPTO_LOCK_MALLOC2
+ * and CRYPTO_LOCK_MALLOC, we'll still be in the right
+ * "case" and "if" branch because MemCheck_start and
+ * MemCheck_stop may never be used while there are multiple
+ * OpenSSL threads. */
CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2);
+ CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
disabling_thread=CRYPTO_thread_id();
}
}