Originally found in 1.0.0j. Did not check versions between 1.0.0j and
1.0.1c since it is still present in the current version.
I am also worried about lines 139-143:
139:if (key-pkey != NULL)
140:{
141:CRYPTO_add(key-pkey-references, 1,
CRYPTO_LOCK_EVP_PKEY);
142:return key-pkey;
143:}
Assume thread 1 runs up to line 140 and some other thread does
EVP_PKEY_free() on the key before thread 1 can get the lock starting in
line 141. Am I overseeing some protection ?
Also note the same problem in lines 175-184:
175:CRYPTO_w_lock(CRYPTO_LOCK_EVP_PKEY);
176:if (key-pkey)
177:{
178:EVP_KEY_free(ret);
179:ret = key-pkey;
180:}
181:else
182:key-pkey = ret;
183:CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY);
184:CRYPTO_add(ret-references, 1, CRYPTO_LOCK_EVP_PKEY);
Assume thread 1 goes up until and finishes line 183, then thread 2 does
EVP_PKEY_free() on key.
I would have supplied patch suggestions for those places as well but I
am not aware of an existing openssl technique of manipulating the
reference counter *without* aquiring a lock, in case we already have a
lock of the correct type.
Regards,
Thomas
diff --git a/crypto/asn1/x_pubkey.c b/crypto/asn1/x_pubkey.c
index 627ec87..d8422ca 100644
--- a/crypto/asn1/x_pubkey.c
+++ b/crypto/asn1/x_pubkey.c
@@ -133,6 +133,7 @@ error:
EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key)
{
EVP_PKEY *ret=NULL;
+ EVP_PKEY *pktmp=NULL;
if (key == NULL) goto error;
@@ -175,7 +176,7 @@ EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key)
CRYPTO_w_lock(CRYPTO_LOCK_EVP_PKEY);
if (key-pkey)
{
- EVP_PKEY_free(ret);
+ pktmp=ret;
ret = key-pkey;
}
else
@@ -183,6 +184,8 @@ EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key)
CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY);
CRYPTO_add(ret-references, 1, CRYPTO_LOCK_EVP_PKEY);
+ if (pktmp)
+ EVP_KEY_free(pktmp);
return ret;
error: