From d04f9b2bd313d078bf421ad522f36d450839abdb Mon Sep 17 00:00:00 2001 From: Tseng Jun Date: Thu, 19 Apr 2018 01:08:09 +0800 Subject: [PATCH] Fix the EVP cipher meth memory leakage problem (#244) * Fix the EVP cipher meth memory leakage problem Looks good, thanks for the fixes. --- src/openssl.c | 82 +++++++++++++++++++++++++++++++++++---------------- src/openssl.h | 3 +- src/pem.c | 2 +- 3 files changed, 60 insertions(+), 27 deletions(-) diff --git a/src/openssl.c b/src/openssl.c index b70b20cf..c15b8430 100644 --- a/src/openssl.c +++ b/src/openssl.c @@ -553,27 +553,27 @@ aes_ctr_cleanup(EVP_CIPHER_CTX *ctx) /* cleanup ctx */ } static const EVP_CIPHER * -make_ctr_evp (size_t keylen, EVP_CIPHER *aes_ctr_cipher, int type) +make_ctr_evp (size_t keylen, EVP_CIPHER **aes_ctr_cipher, int type) { #ifdef HAVE_OPAQUE_STRUCTS - aes_ctr_cipher = EVP_CIPHER_meth_new(type, 16, keylen); - if(aes_ctr_cipher) { - EVP_CIPHER_meth_set_iv_length(aes_ctr_cipher, 16); - EVP_CIPHER_meth_set_init(aes_ctr_cipher, aes_ctr_init); - EVP_CIPHER_meth_set_do_cipher(aes_ctr_cipher, aes_ctr_do_cipher); - EVP_CIPHER_meth_set_cleanup(aes_ctr_cipher, aes_ctr_cleanup); + *aes_ctr_cipher = EVP_CIPHER_meth_new(type, 16, keylen); + if(*aes_ctr_cipher) { + EVP_CIPHER_meth_set_iv_length(*aes_ctr_cipher, 16); + EVP_CIPHER_meth_set_init(*aes_ctr_cipher, aes_ctr_init); + EVP_CIPHER_meth_set_do_cipher(*aes_ctr_cipher, aes_ctr_do_cipher); + EVP_CIPHER_meth_set_cleanup(*aes_ctr_cipher, aes_ctr_cleanup); } #else - aes_ctr_cipher->nid = type; - aes_ctr_cipher->block_size = 16; - aes_ctr_cipher->key_len = keylen; - aes_ctr_cipher->iv_len = 16; - aes_ctr_cipher->init = aes_ctr_init; - aes_ctr_cipher->do_cipher = aes_ctr_do_cipher; - aes_ctr_cipher->cleanup = aes_ctr_cleanup; + *aes_ctr_cipher->nid = type; + *aes_ctr_cipher->block_size = 16; + *aes_ctr_cipher->key_len = keylen; + *aes_ctr_cipher->iv_len = 16; + *aes_ctr_cipher->init = aes_ctr_init; + *aes_ctr_cipher->do_cipher = aes_ctr_do_cipher; + *aes_ctr_cipher->cleanup = aes_ctr_cleanup; #endif - return aes_ctr_cipher; + return *aes_ctr_cipher; } const EVP_CIPHER * @@ -582,11 +582,12 @@ _libssh2_EVP_aes_128_ctr(void) #ifdef HAVE_OPAQUE_STRUCTS static EVP_CIPHER * aes_ctr_cipher; return !aes_ctr_cipher ? - make_ctr_evp(16, aes_ctr_cipher, NID_aes_128_ctr) : aes_ctr_cipher; + make_ctr_evp(16, &aes_ctr_cipher, NID_aes_128_ctr) : aes_ctr_cipher; #else static EVP_CIPHER aes_ctr_cipher; + static EVP_CIPHER * aes_ctr_cipher_ptr = &aes_ctr_cipher; return !aes_ctr_cipher.key_len ? - make_ctr_evp(16, &aes_ctr_cipher, 0) : &aes_ctr_cipher; + make_ctr_evp(16, &aes_ctr_cipher_ptr, 0) : &aes_ctr_cipher; #endif } @@ -596,11 +597,12 @@ _libssh2_EVP_aes_192_ctr(void) #ifdef HAVE_OPAQUE_STRUCTS static EVP_CIPHER * aes_ctr_cipher; return !aes_ctr_cipher ? - make_ctr_evp(24, aes_ctr_cipher, NID_aes_192_ctr) : aes_ctr_cipher; + make_ctr_evp(24, &aes_ctr_cipher, NID_aes_192_ctr) : aes_ctr_cipher; #else static EVP_CIPHER aes_ctr_cipher; + static EVP_CIPHER * aes_ctr_cipher_ptr = &aes_ctr_cipher; return !aes_ctr_cipher.key_len ? - make_ctr_evp(24, &aes_ctr_cipher, 0) : &aes_ctr_cipher; + make_ctr_evp(24, &aes_ctr_cipher_ptr, 0) : &aes_ctr_cipher; #endif } @@ -610,16 +612,23 @@ _libssh2_EVP_aes_256_ctr(void) #ifdef HAVE_OPAQUE_STRUCTS static EVP_CIPHER * aes_ctr_cipher; return !aes_ctr_cipher ? - make_ctr_evp(32, aes_ctr_cipher, NID_aes_256_ctr) : aes_ctr_cipher; + make_ctr_evp(32, &aes_ctr_cipher, NID_aes_256_ctr) : aes_ctr_cipher; #else static EVP_CIPHER aes_ctr_cipher; + static EVP_CIPHER * aes_ctr_cipher_ptr = &aes_ctr_cipher; return !aes_ctr_cipher.key_len ? - make_ctr_evp(32, &aes_ctr_cipher, 0) : &aes_ctr_cipher; + make_ctr_evp(32, &aes_ctr_cipher_ptr, 0) : &aes_ctr_cipher; #endif } #endif /* LIBSSH2_AES_CTR */ +#ifndef HAVE_EVP_AES_128_CTR +static EVP_CIPHER * aes_128_ctr_cipher = NULL; +static EVP_CIPHER * aes_192_ctr_cipher = NULL; +static EVP_CIPHER * aes_256_ctr_cipher = NULL; +#endif + void _libssh2_openssl_crypto_init(void) { #if OPENSSL_VERSION_NUMBER >= 0x10100000L @@ -632,9 +641,32 @@ void _libssh2_openssl_crypto_init(void) ENGINE_register_all_complete(); #endif #ifndef HAVE_EVP_AES_128_CTR - _libssh2_EVP_aes_128_ctr(); - _libssh2_EVP_aes_192_ctr(); - _libssh2_EVP_aes_256_ctr(); + aes_128_ctr_cipher = (EVP_CIPHER *)_libssh2_EVP_aes_128_ctr(); + aes_192_ctr_cipher = (EVP_CIPHER *)_libssh2_EVP_aes_192_ctr(); + aes_256_ctr_cipher = (EVP_CIPHER *)_libssh2_EVP_aes_256_ctr(); +#endif +} + +void _libssh2_openssl_crypto_exit(void) +{ +#ifndef HAVE_EVP_AES_128_CTR +#ifdef HAVE_OPAQUE_STRUCTS + if(aes_128_ctr_cipher) { + EVP_CIPHER_meth_free(aes_128_ctr_cipher); + } + + if(aes_192_ctr_cipher) { + EVP_CIPHER_meth_free(aes_192_ctr_cipher); + } + + if(aes_256_ctr_cipher) { + EVP_CIPHER_meth_free(aes_256_ctr_cipher); + } +#endif + + aes_128_ctr_cipher = NULL; + aes_192_ctr_cipher = NULL; + aes_256_ctr_cipher = NULL; #endif } @@ -1558,7 +1590,7 @@ _libssh2_ecdsa_create_key(_libssh2_ec_key **out_private_key, if(out_public_key_octal) { *out_public_key_octal = malloc(octal_len); - if(out_public_key_octal == NULL) { + if(*out_public_key_octal == NULL) { ret = -1; goto clean_exit; } diff --git a/src/openssl.h b/src/openssl.h index 35a1246e..627bddbf 100644 --- a/src/openssl.h +++ b/src/openssl.h @@ -281,8 +281,9 @@ int _libssh2_md5_init(libssh2_md5_ctx *ctx); #endif extern void _libssh2_openssl_crypto_init(void); +extern void _libssh2_openssl_crypto_exit(void); #define libssh2_crypto_init() _libssh2_openssl_crypto_init() -#define libssh2_crypto_exit() +#define libssh2_crypto_exit() _libssh2_openssl_crypto_exit() #define libssh2_rsa_ctx RSA diff --git a/src/pem.c b/src/pem.c index 4fa02bb5..7c636430 100644 --- a/src/pem.c +++ b/src/pem.c @@ -254,7 +254,7 @@ _libssh2_pem_parse(LIBSSH2_SESSION * session, goto out; } - while(len_decrypted <= *datalen - blocksize) { + while(len_decrypted <= (int)*datalen - blocksize) { if(method->crypt(session, *data + len_decrypted, blocksize, &abstract)) { ret = LIBSSH2_ERROR_DECRYPT;