From 748cb9a17f4f2b77aad816cf658cd4025dc847ee Mon Sep 17 00:00:00 2001 From: Bernd Edlinger Date: Wed, 21 Dec 2016 11:21:36 +0100 Subject: 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 Reviewed-by: Rich Salz (Merged from https://github.com/openssl/openssl/pull/2127) --- crypto/ex_data.c | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) (limited to 'crypto/ex_data.c') 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; } /********************************************************************/ -- cgit v1.2.3