From 508203da9bf31b71e60d0899ac008903298f3a58 Mon Sep 17 00:00:00 2001 From: Hans Meier Date: Wed, 26 Feb 2020 20:06:12 +0100 Subject: [PATCH] openssl.c: Fix use-after-free crash in openssl backend without memory leak (#439) Files: openssl.c Notes: Fixes memory leaks and use after free AES EVP_CIPHER contexts when using OpenSSL 1.0.x. Credit: Hans Meier --- src/openssl.c | 45 ++++++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/src/openssl.c b/src/openssl.c index d4cf401..d5ad702 100644 --- a/src/openssl.c +++ b/src/openssl.c @@ -433,6 +433,12 @@ _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx, return ret == 1 ? 0 : 1; } +#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 + #if LIBSSH2_AES_CTR && !defined(HAVE_EVP_AES_128_CTR) #include @@ -589,12 +595,14 @@ const EVP_CIPHER * _libssh2_EVP_aes_128_ctr(void) { #ifdef HAVE_OPAQUE_STRUCTS - EVP_CIPHER * aes_ctr_cipher; - return make_ctr_evp(16, &aes_ctr_cipher, NID_aes_128_ctr); + return !aes_128_ctr_cipher ? + make_ctr_evp(16, &aes_128_ctr_cipher, NID_aes_128_ctr) : + aes_128_ctr_cipher; #else static EVP_CIPHER aes_ctr_cipher; - EVP_CIPHER * aes_ctr_cipher_ptr = &aes_ctr_cipher; - return make_ctr_evp(16, &aes_ctr_cipher_ptr, 0); + static EVP_CIPHER * aes_ctr_cipher_ptr = &aes_ctr_cipher; + return !aes_ctr_cipher.key_len ? + make_ctr_evp(16, &aes_ctr_cipher_ptr, 0) : &aes_ctr_cipher; #endif } @@ -602,12 +610,14 @@ const EVP_CIPHER * _libssh2_EVP_aes_192_ctr(void) { #ifdef HAVE_OPAQUE_STRUCTS - EVP_CIPHER * aes_ctr_cipher; - return make_ctr_evp(24, &aes_ctr_cipher, NID_aes_192_ctr); + return !aes_192_ctr_cipher ? + make_ctr_evp(24, &aes_192_ctr_cipher, NID_aes_192_ctr) : + aes_192_ctr_cipher; #else static EVP_CIPHER aes_ctr_cipher; - EVP_CIPHER * aes_ctr_cipher_ptr = &aes_ctr_cipher; - return make_ctr_evp(24, &aes_ctr_cipher_ptr, 0); + static EVP_CIPHER * aes_ctr_cipher_ptr = &aes_ctr_cipher; + return !aes_ctr_cipher.key_len ? + make_ctr_evp(24, &aes_ctr_cipher_ptr, 0) : &aes_ctr_cipher; #endif } @@ -615,23 +625,19 @@ const EVP_CIPHER * _libssh2_EVP_aes_256_ctr(void) { #ifdef HAVE_OPAQUE_STRUCTS - EVP_CIPHER * aes_ctr_cipher; - return make_ctr_evp(32, &aes_ctr_cipher, NID_aes_256_ctr); + return !aes_256_ctr_cipher ? + make_ctr_evp(32, &aes_256_ctr_cipher, NID_aes_256_ctr) : + aes_256_ctr_cipher; #else static EVP_CIPHER aes_ctr_cipher; - EVP_CIPHER * aes_ctr_cipher_ptr = &aes_ctr_cipher; - return make_ctr_evp(32, &aes_ctr_cipher_ptr, 0); + static EVP_CIPHER * aes_ctr_cipher_ptr = &aes_ctr_cipher; + return !aes_ctr_cipher.key_len ? + 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 && \ @@ -650,11 +656,8 @@ void _libssh2_openssl_crypto_init(void) #endif #endif #ifndef HAVE_EVP_AES_128_CTR - if(!aes_128_ctr_cipher) aes_128_ctr_cipher = (EVP_CIPHER *) _libssh2_EVP_aes_128_ctr(); - if(!aes_192_ctr_cipher) aes_192_ctr_cipher = (EVP_CIPHER *) _libssh2_EVP_aes_192_ctr(); - if(!aes_256_ctr_cipher) aes_256_ctr_cipher = (EVP_CIPHER *) _libssh2_EVP_aes_256_ctr(); #endif }