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;