[RCF::OpenSSL] Memory Leak !

RCF support and general discussion.
Post Reply
acDev
Posts: 27
Joined: Tue Oct 08, 2013 3:08 pm
Location: Moscow
Contact:

[RCF::OpenSSL] Memory Leak !

Post by acDev »

Visual Leak Detector:

Code: Select all

src\rcf\opensslencryptionfilter.cpp (269):  Server.exe!RCF::Globals::getOpenSslCryptoDll + 0x28 bytes
src\rcf\opensslencryptionfilter.cpp (778):  Server.exe!RCF::OpenSslEncryptionFilterImpl::OpenSslEncryptionFilterImpl + 0x66 bytes
src\rcf\opensslencryptionfilter.cpp (643):  Server.exe!RCF::OpenSslEncryptionFilter::OpenSslEncryptionFilter + 0xCE bytes
src\rcf\opensslencryptionfilter.cpp (1267): Server.exe!RCF::OpenSslEncryptionFilterFactory::createFilter + 0x67 bytes
src\rcf\filterservice.cpp           (106):  Server.exe!RCF::FilterService::RequestTransportFilters + 0x2E bytes

acDev
Posts: 27
Joined: Tue Oct 08, 2013 3:08 pm
Location: Moscow
Contact:

Re: [RCF::OpenSSL] Memory Leak !

Post by acDev »

Requered call fuctions:

Code: Select all

CONF_modules_free();
ERR_remove_state(0);
ENGINE_cleanup();
CONF_modules_unload(1);
ERR_free_strings();
EVP_cleanup();
CRYPTO_cleanup_all_ex_data();
sk_free(SSL_COMP_get_compression_methods());
Fix sources.

DynamicLib.hpp

Code: Select all

 #define RCF_LOAD_LIB_FUNCTION(funcName)                                     \
     pfn_##funcName = & funcName;
 
+#define RCF_LOAD_LIB_FUNCTION_FORCE(funcName)                               \
+    pfn_##funcName = (Pfn_##funcName) & funcName;
+
 } // namespace RCF
 
 #endif // ! INCLUDE_RCF_DYNAMICLIB_HPP
Globals.hpp

Code: Select all

         OpenSslDll &        getOpenSslDll();
         OpenSslCryptoDll &  getOpenSslCryptoDll();
 
+        void                destroyZlibLib();
+        void                destroyOpenSslDll();   // also OpenSslCryptoDll
+
     private:
 
         ZlibDll *           mpZlibDll;
Globals.cpp

Code: Select all

 
     Globals::~Globals()
     {
+#if RCF_FEATURE_ZLIB==1
+        destroyZlibLib();
+#endif
+
+#if RCF_FEATURE_OPENSSL==1        
+        destroyOpenSslDll();
+#endif        
     }
 
     void Globals::setZlibDllName(const std::string & dllName)
ZlibCompressionFilter.cpp

Code: Select all

         }
         return *mpZlibDll;
     }
+    
+    void Globals::destroyZlibLib()
+    {
+        if (mpZlibDll) delete mpZlibDll;
+        mpZlibDll = NULL;
+    }
 
     class ZlibCompressionReadFilter
     {
OpenSslEncryptionFilter.cpp

Code: Select all

@@ -39,9 +39,11 @@
 namespace RCF {
 
 #ifdef RCF_USE_OPENSSL_STATIC
-#define RCF_OPENSSL_LOAD_FUNC(_fn_name_)   RCF_LOAD_LIB_FUNCTION(_fn_name_)
+#define RCF_OPENSSL_LOAD_FUNC(_fn_name_)         RCF_LOAD_LIB_FUNCTION(_fn_name_)
+#define RCF_OPENSSL_LOAD_FUNC_FORCE(_fn_name_)   RCF_LOAD_LIB_FUNCTION_FORCE(_fn_name_)
 #else 
-#define RCF_OPENSSL_LOAD_FUNC(_fn_name_)   RCF_LOAD_DLL_FUNCTION(_fn_name_)
+#define RCF_OPENSSL_LOAD_FUNC(_fn_name_)         RCF_LOAD_DLL_FUNCTION(_fn_name_)
+#define RCF_OPENSSL_LOAD_FUNC_FORCE(_fn_name_)   RCF_LOAD_DLL_FUNCTION(_fn_name_)
 #endif    
 
     class OpenSslDll
@@ -71,6 +73,8 @@
         typedef int             (*Pfn_SSL_CTX_load_verify_locations)(SSL_CTX *ctx, const char *CAfile, const char *CApath);
         typedef void            (*Pfn_SSL_load_error_strings)(void );
         typedef int             (*Pfn_SSL_library_init)(void );
+        
+        typedef void *          (*Pfn_SSL_COMP_get_compression_methods)(void);
 
         Pfn_SSL_get_verify_result               pfn_SSL_get_verify_result;
         Pfn_SSL_get_peer_certificate            pfn_SSL_get_peer_certificate;
@@ -89,7 +93,9 @@
         Pfn_SSL_CTX_use_certificate_chain_file  pfn_SSL_CTX_use_certificate_chain_file;
         Pfn_SSL_CTX_load_verify_locations       pfn_SSL_CTX_load_verify_locations;
         Pfn_SSL_load_error_strings              pfn_SSL_load_error_strings;
-        Pfn_SSL_library_init                    pfn_SSL_library_init;       
+        Pfn_SSL_library_init                    pfn_SSL_library_init;
+        
+        Pfn_SSL_COMP_get_compression_methods    pfn_SSL_COMP_get_compression_methods;
     };
 
     class OpenSslCryptoDll
@@ -128,6 +134,15 @@
         typedef X509_NAME *     (*Pfn_X509_get_issuer_name)(X509 *a);
         typedef int             (*Pfn_X509_NAME_print_ex)(BIO *out, X509_NAME *nm, int indent, unsigned long flags);
 
+        typedef void            (*Pfn_ERR_free_strings)(void);
+        typedef void            (*Pfn_CONF_modules_free)(void);
+        typedef void            (*Pfn_ERR_remove_state)(unsigned long pid);     /* if zero we look it up */ 
+        typedef void            (*Pfn_ENGINE_cleanup)(void);
+        typedef void            (*Pfn_CONF_modules_unload)(int all);
+        typedef void            (*Pfn_EVP_cleanup)(void);
+        typedef void            (*Pfn_CRYPTO_cleanup_all_ex_data)(void);
+        typedef void            (*Pfn_sk_free)(void *);   // _STACK *
+
         Pfn_BIO_ctrl_pending                    pfn_BIO_ctrl_pending;
         Pfn_BIO_write                           pfn_BIO_write;
         Pfn_BIO_read                            pfn_BIO_read;
@@ -145,7 +160,7 @@
         Pfn_ERR_print_errors_cb                 pfn_ERR_print_errors_cb;
         Pfn_ERR_print_errors                    pfn_ERR_print_errors;
         Pfn_BIO_s_mem                           pfn_BIO_s_mem;
-        Pfn_ERR_load_crypto_strings             pfn_ERR_load_crypto_strings;
+        Pfn_ERR_load_crypto_strings             pfn_ERR_load_crypto_strings;        
         Pfn_BIO_test_flags                      pfn_BIO_test_flags;
         Pfn_X509_free                           pfn_X509_free;
         Pfn_PEM_read_bio_PrivateKey             pfn_PEM_read_bio_PrivateKey;
@@ -153,6 +168,16 @@
         Pfn_X509_get_subject_name               pfn_X509_get_subject_name;
         Pfn_X509_get_issuer_name                pfn_X509_get_issuer_name;
         Pfn_X509_NAME_print_ex                  pfn_X509_NAME_print_ex;
+        
+        Pfn_ERR_free_strings                    pfn_ERR_free_strings;
+        Pfn_CONF_modules_free                   pfn_CONF_modules_free;
+        Pfn_ERR_remove_state                    pfn_ERR_remove_state;
+        Pfn_ENGINE_cleanup                      pfn_ENGINE_cleanup;
+        Pfn_CONF_modules_unload                 pfn_CONF_modules_unload;
+        Pfn_EVP_cleanup                         pfn_EVP_cleanup;
+        Pfn_CRYPTO_cleanup_all_ex_data          pfn_CRYPTO_cleanup_all_ex_data;
+        Pfn_sk_free                             pfn_sk_free;
+        
     };
 
@@ -192,6 +218,8 @@
         RCF_OPENSSL_LOAD_FUNC(SSL_CTX_load_verify_locations);
         RCF_OPENSSL_LOAD_FUNC(SSL_load_error_strings);
         RCF_OPENSSL_LOAD_FUNC(SSL_library_init);
+        
+        RCF_OPENSSL_LOAD_FUNC_FORCE(SSL_COMP_get_compression_methods);
     }
 
@@ -240,7 +269,15 @@
         RCF_OPENSSL_LOAD_FUNC(X509_get_subject_name);
         RCF_OPENSSL_LOAD_FUNC(X509_get_issuer_name);
         RCF_OPENSSL_LOAD_FUNC(X509_NAME_print_ex);
-        
+
+        RCF_OPENSSL_LOAD_FUNC(ERR_free_strings); 
+        RCF_OPENSSL_LOAD_FUNC(CONF_modules_free);
+        RCF_OPENSSL_LOAD_FUNC(ERR_remove_state);
+        RCF_OPENSSL_LOAD_FUNC(ENGINE_cleanup);
+        RCF_OPENSSL_LOAD_FUNC(CONF_modules_unload);
+        RCF_OPENSSL_LOAD_FUNC(EVP_cleanup);
+        RCF_OPENSSL_LOAD_FUNC(CRYPTO_cleanup_all_ex_data);
+        RCF_OPENSSL_LOAD_FUNC_FORCE(sk_free);
     }
 
     OpenSslDll & Globals::getOpenSslDll()
@@ -253,7 +290,7 @@
         }
         return *mpOpenSslDll;
     }
-
+    
     OpenSslCryptoDll & Globals::getOpenSslCryptoDll()
     {
         Lock lock(getRootMutex());
@@ -265,6 +302,29 @@
         return *mpOpenSslCryptoDll;
     }
 
+    void Globals::destroyOpenSslDll()
+    {           
+        if (mpOpenSslCryptoDll) {
+            mpOpenSslCryptoDll->pfn_CONF_modules_free();
+            mpOpenSslCryptoDll->pfn_ERR_remove_state(0);
+            mpOpenSslCryptoDll->pfn_ENGINE_cleanup();
+            mpOpenSslCryptoDll->pfn_CONF_modules_unload(1);
+            mpOpenSslCryptoDll->pfn_ERR_free_strings();
+            mpOpenSslCryptoDll->pfn_EVP_cleanup();
+            mpOpenSslCryptoDll->pfn_CRYPTO_cleanup_all_ex_data();
+            if (mpOpenSslDll) {
+              void * stack = mpOpenSslDll->pfn_SSL_COMP_get_compression_methods();
+              if (stack) mpOpenSslCryptoDll->pfn_sk_free(stack);
+            }
+            delete mpOpenSslCryptoDll;
+            mpOpenSslCryptoDll = NULL;
+        }
+        if (mpOpenSslDll) {
+            delete mpOpenSslDll;
+            mpOpenSslDll = NULL;
+        }
+    }
+
 #define SSL_get_verify_result                   mSslDll.pfn_SSL_get_verify_result
 #define SSL_get_peer_certificate                mSslDll.pfn_SSL_get_peer_certificate
 #define SSL_state                               mSslDll.pfn_SSL_state

jarl
Posts: 238
Joined: Mon Oct 03, 2011 4:53 am
Contact:

Re: [RCF::OpenSSL] Memory Leak !

Post by jarl »

This has been fixed in the codebase. In any case, you should see at most one instance of this leak while your program is running.
Kind Regards

Jarl Lindrud
Delta V Software
http://www.deltavsoft.com

Post Reply