summaryrefslogtreecommitdiffstats
path: root/crypto/ex_data.c
diff options
context:
space:
mode:
authorBernd Edlinger <bernd.edlinger@hotmail.de>2016-12-21 11:21:36 +0100
committerRich Salz <rsalz@openssl.org>2017-02-06 16:06:39 -0500
commit748cb9a17f4f2b77aad816cf658cd4025dc847ee (patch)
tree28ee694bfe96e0804bd1cf9fb1149a67d2ead2eb /crypto/ex_data.c
parentefe8398649a1d7fc9d84d2818592652e0632a8a8 (diff)
Combined patch for the more or less obvious issues
Fixed a memory leak in ASN1_digest and ASN1_item_digest. asn1_template_noexp_d2i call ASN1_item_ex_free(&skfield,...) on error. Reworked error handling in asn1_item_ex_combine_new: - call ASN1_item_ex_free and return the correct error code if ASN1_template_new failed. - dont call ASN1_item_ex_free if ASN1_OP_NEW_PRE failed. Reworked error handing in x509_name_ex_d2i and x509_name_encode. Fixed error handling in int_ctx_new and EVP_PKEY_CTX_dup. Fixed a memory leak in def_get_class if lh_EX_CLASS_ITEM_insert fails due to OOM: - to figure out if the insertion succeeded, use lh_EX_CLASS_ITEM_retrieve again. - on error, p will be NULL, and gen needs to be cleaned up again. int_free_ex_data needs to have a fallback solution if unable to allocate "storage": - if free_func is non-zero this must be called to clean up all memory. Fixed error handling in pkey_hmac_copy. Fixed error handling in ssleay_rand_add and ssleay_rand_bytes. Fixed error handling in X509_STORE_new. Fixed a memory leak in ssl3_get_key_exchange. Check for null pointer in ssl3_write_bytes. Check for null pointer in ssl3_get_cert_verify. Fixed a memory leak in ssl_cert_dup. Fixes #2087 #2094 #2103 #2104 #2105 #2106 #2107 #2108 #2110 #2111 #2112 #2115 Reviewed-by: Richard Levitte <levitte@openssl.org> Reviewed-by: Rich Salz <rsalz@openssl.org> (Merged from https://github.com/openssl/openssl/pull/2127)
Diffstat (limited to 'crypto/ex_data.c')
-rw-r--r--crypto/ex_data.c37
1 files changed, 21 insertions, 16 deletions
diff --git a/crypto/ex_data.c b/crypto/ex_data.c
index f96a51781a..d947f3edac 100644
--- a/crypto/ex_data.c
+++ b/crypto/ex_data.c
@@ -331,7 +331,11 @@ static EX_CLASS_ITEM *def_get_class(int class_index)
* from the insert will be NULL
*/
(void)lh_EX_CLASS_ITEM_insert(ex_data, gen);
- p = gen;
+ p = lh_EX_CLASS_ITEM_retrieve(ex_data, &d);
+ if (p != gen) {
+ sk_CRYPTO_EX_DATA_FUNCS_free(gen->meth);
+ OPENSSL_free(gen);
+ }
}
}
}
@@ -499,11 +503,12 @@ static void int_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
int mx, i;
EX_CLASS_ITEM *item;
void *ptr;
+ CRYPTO_EX_DATA_FUNCS *f;
CRYPTO_EX_DATA_FUNCS **storage = NULL;
if (ex_data == NULL)
- return;
+ goto err;
if ((item = def_get_class(class_index)) == NULL)
- return;
+ goto err;
CRYPTO_r_lock(CRYPTO_LOCK_EX_DATA);
mx = sk_CRYPTO_EX_DATA_FUNCS_num(item->meth);
if (mx > 0) {
@@ -515,23 +520,23 @@ static void int_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
}
skip:
CRYPTO_r_unlock(CRYPTO_LOCK_EX_DATA);
- if ((mx > 0) && !storage) {
- CRYPTOerr(CRYPTO_F_INT_FREE_EX_DATA, ERR_R_MALLOC_FAILURE);
- return;
- }
for (i = 0; i < mx; i++) {
- if (storage[i] && storage[i]->free_func) {
+ if (storage != NULL)
+ f = storage[i];
+ else {
+ CRYPTO_r_lock(CRYPTO_LOCK_EX_DATA);
+ f = sk_CRYPTO_EX_DATA_FUNCS_value(item->meth, i);
+ CRYPTO_r_unlock(CRYPTO_LOCK_EX_DATA);
+ }
+ if (f != NULL && f->free_func != NULL) {
ptr = CRYPTO_get_ex_data(ad, i);
- storage[i]->free_func(obj, ptr, ad, i,
- storage[i]->argl, storage[i]->argp);
+ f->free_func(obj, ptr, ad, i, f->argl, f->argp);
}
}
- if (storage)
- OPENSSL_free(storage);
- if (ad->sk) {
- sk_void_free(ad->sk);
- ad->sk = NULL;
- }
+ OPENSSL_free(storage);
+ err:
+ sk_void_free(ad->sk);
+ ad->sk = NULL;
}
/********************************************************************/