Do not leak ex_data for SSL state that survived reconfigure.

SSL_get_ex_new_index() allocates a new index on every call, even if its
parameters remain unchanged. It should be called once per process lifetime.

Besides leaking, this 12 year-old(!) bug could probably make some SSL
code misbehave during reconfigure because reconfigure would change the
supposedly constant ex_data indexes.

Alex.

Do not leak ex_data for SSL state that survived reconfigure.

SSL_get_ex_new_index() allocates a new index on every call, even if its
parameters remain unchanged. It should be called once per process lifetime.

Besides leaking, this 12 year-old(!) bug could probably make some SSL code
misbehave during reconfigure because reconfigure would change the supposedly
constant ex_data indexes.

=== modified file 'src/ssl/support.cc'
--- src/ssl/support.cc	2014-03-30 12:00:34 +0000
+++ src/ssl/support.cc	2014-04-24 20:37:38 +0000
@@ -694,69 +694,69 @@ static void
 ssl_free_CertChain(void *, void *ptr, CRYPTO_EX_DATA *,
                    int, long, void *)
 {
     STACK_OF(X509) *certsChain = static_cast <STACK_OF(X509) *>(ptr);
     sk_X509_pop_free(certsChain,X509_free);
 }
 
 // "free" function for X509 certificates
 static void
 ssl_free_X509(void *, void *ptr, CRYPTO_EX_DATA *,
               int, long, void *)
 {
     X509  *cert = static_cast <X509 *>(ptr);
     X509_free(cert);
 }
 
 /// \ingroup ServerProtocolSSLInternal
 static void
 ssl_initialize(void)
 {
-    static int ssl_initialized = 0;
+    static bool initialized = false;
+    if (initialized)
+        return;
+    initialized = true;
 
-    if (!ssl_initialized) {
-        ssl_initialized = 1;
         SSL_load_error_strings();
         SSLeay_add_ssl_algorithms();
 #if HAVE_OPENSSL_ENGINE_H
 
         if (Config.SSL.ssl_engine) {
             ENGINE *e;
 
             if (!(e = ENGINE_by_id(Config.SSL.ssl_engine))) {
                 fatalf("Unable to find SSL engine '%s'\n", Config.SSL.ssl_engine);
             }
 
             if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) {
                 int ssl_error = ERR_get_error();
                 fatalf("Failed to initialise SSL engine: %s\n",
                        ERR_error_string(ssl_error, NULL));
             }
         }
 
 #else
         if (Config.SSL.ssl_engine) {
             fatalf("Your OpenSSL has no SSL engine support\n");
         }
 
 #endif
-    }
 
     ssl_ex_index_server = SSL_get_ex_new_index(0, (void *) "server", NULL, NULL, NULL);
     ssl_ctx_ex_index_dont_verify_domain = SSL_CTX_get_ex_new_index(0, (void *) "dont_verify_domain", NULL, NULL, NULL);
     ssl_ex_index_cert_error_check = SSL_get_ex_new_index(0, (void *) "cert_error_check", NULL, &ssl_dupAclChecklist, &ssl_freeAclChecklist);
     ssl_ex_index_ssl_error_detail = SSL_get_ex_new_index(0, (void *) "ssl_error_detail", NULL, NULL, &ssl_free_ErrorDetail);
     ssl_ex_index_ssl_peeked_cert  = SSL_get_ex_new_index(0, (void *) "ssl_peeked_cert", NULL, NULL, &ssl_free_X509);
     ssl_ex_index_ssl_errors =  SSL_get_ex_new_index(0, (void *) "ssl_errors", NULL, NULL, &ssl_free_SslErrors);
     ssl_ex_index_ssl_cert_chain = SSL_get_ex_new_index(0, (void *) "ssl_cert_chain", NULL, NULL, &ssl_free_CertChain);
     ssl_ex_index_ssl_validation_counter = SSL_get_ex_new_index(0, (void *) "ssl_validation_counter", NULL, NULL, &ssl_free_int);
 }
 
 /// \ingroup ServerProtocolSSLInternal
 static int
 ssl_load_crl(SSL_CTX *sslContext, const char *CRLfile)
 {
     X509_STORE *st = SSL_CTX_get_cert_store(sslContext);
     X509_CRL *crl;
     BIO *in = BIO_new_file(CRLfile, "r");
     int count = 0;
 

Reply via email to