Fix memory leak of SSL_CTX structures in TLS core.

SSL_CTX structures were allocated but never freed. This was a bigger
issue for clients than servers since new SSL_CTX structures could be
allocated for each connection. Servers, on the other hand, typically
set up a single SSL_CTX for their lifetime.

This is solved in two ways:

1. In __ssl_setup(), if a tcptls_cfg has an ssl_ctx on it, it is
freed so that a new one can take its place.
2. A companion to ast_ssl_setup() called ast_ssl_teardown() has
been added so that servers can properly free their SSL_CTXs.

(issue ASTERISK-19278)



git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.8@367002 65c4cc65-6c06-0410-ace0-fbb531ad65f3
certified/1.8.15
Mark Michelson 14 years ago
parent 67268d9198
commit eef4c09787

@ -30603,6 +30603,7 @@ static int unload_module(void)
if (sip_tls_desc.master) { if (sip_tls_desc.master) {
ast_tcptls_server_stop(&sip_tls_desc); ast_tcptls_server_stop(&sip_tls_desc);
} }
ast_ssl_teardown(sip_tls_desc.tls_cfg);
/* Kill all existing TCP/TLS threads */ /* Kill all existing TCP/TLS threads */
i = ao2_iterator_init(threadt, 0); i = ao2_iterator_init(threadt, 0);

@ -190,8 +190,25 @@ void ast_tcptls_server_start(struct ast_tcptls_session_args *desc);
* \version 1.6.1 changed desc parameter to be of ast_tcptls_session_args type * \version 1.6.1 changed desc parameter to be of ast_tcptls_session_args type
*/ */
void ast_tcptls_server_stop(struct ast_tcptls_session_args *desc); void ast_tcptls_server_stop(struct ast_tcptls_session_args *desc);
/*!
* \brief Set up an SSL server
*
* \param cfg Configuration for the SSL server
* \retval 1 Success
* \retval 0 Failure
*/
int ast_ssl_setup(struct ast_tls_config *cfg); int ast_ssl_setup(struct ast_tls_config *cfg);
/*!
* \brief free resources used by an SSL server
*
* \note This only needs to be called if ast_ssl_setup() was
* directly called first.
* \param cfg Configuration for the SSL server
*/
void ast_ssl_teardown(struct ast_tls_config *cfg);
/*! /*!
* \brief Used to parse conf files containing tls/ssl options. * \brief Used to parse conf files containing tls/ssl options.
*/ */

@ -130,6 +130,9 @@ HOOK_T ast_tcptls_server_write(struct ast_tcptls_session_instance *tcptls_sessio
static void session_instance_destructor(void *obj) static void session_instance_destructor(void *obj)
{ {
struct ast_tcptls_session_instance *i = obj; struct ast_tcptls_session_instance *i = obj;
if (i->parent && i->parent->tls_cfg) {
ast_ssl_teardown(i->parent->tls_cfg);
}
ast_mutex_destroy(&i->lock); ast_mutex_destroy(&i->lock);
} }
@ -311,6 +314,14 @@ static int __ssl_setup(struct ast_tls_config *cfg, int client)
SSL_load_error_strings(); SSL_load_error_strings();
SSLeay_add_ssl_algorithms(); SSLeay_add_ssl_algorithms();
/* Get rid of an old SSL_CTX since we're about to
* allocate a new one
*/
if (cfg->ssl_ctx) {
SSL_CTX_free(cfg->ssl_ctx);
cfg->ssl_ctx = NULL;
}
if (client) { if (client) {
#ifndef OPENSSL_NO_SSL2 #ifndef OPENSSL_NO_SSL2
if (ast_test_flag(&cfg->flags, AST_SSL_SSLV2_CLIENT)) { if (ast_test_flag(&cfg->flags, AST_SSL_SSLV2_CLIENT)) {
@ -346,6 +357,8 @@ static int __ssl_setup(struct ast_tls_config *cfg, int client)
ast_verb(0, "SSL error loading cert file. <%s>", cfg->certfile); ast_verb(0, "SSL error loading cert file. <%s>", cfg->certfile);
sleep(2); sleep(2);
cfg->enabled = 0; cfg->enabled = 0;
SSL_CTX_free(cfg->ssl_ctx);
cfg->ssl_ctx = NULL;
return 0; return 0;
} }
} }
@ -355,6 +368,8 @@ static int __ssl_setup(struct ast_tls_config *cfg, int client)
ast_verb(0, "SSL error loading private key file. <%s>", tmpprivate); ast_verb(0, "SSL error loading private key file. <%s>", tmpprivate);
sleep(2); sleep(2);
cfg->enabled = 0; cfg->enabled = 0;
SSL_CTX_free(cfg->ssl_ctx);
cfg->ssl_ctx = NULL;
return 0; return 0;
} }
} }
@ -365,6 +380,8 @@ static int __ssl_setup(struct ast_tls_config *cfg, int client)
ast_verb(0, "SSL cipher error <%s>", cfg->cipher); ast_verb(0, "SSL cipher error <%s>", cfg->cipher);
sleep(2); sleep(2);
cfg->enabled = 0; cfg->enabled = 0;
SSL_CTX_free(cfg->ssl_ctx);
cfg->ssl_ctx = NULL;
return 0; return 0;
} }
} }
@ -384,6 +401,14 @@ int ast_ssl_setup(struct ast_tls_config *cfg)
return __ssl_setup(cfg, 0); return __ssl_setup(cfg, 0);
} }
void ast_ssl_teardown(struct ast_tls_config *cfg)
{
if (cfg->ssl_ctx) {
SSL_CTX_free(cfg->ssl_ctx);
cfg->ssl_ctx = NULL;
}
}
struct ast_tcptls_session_instance *ast_tcptls_client_start(struct ast_tcptls_session_instance *tcptls_session) struct ast_tcptls_session_instance *ast_tcptls_client_start(struct ast_tcptls_session_instance *tcptls_session)
{ {
struct ast_tcptls_session_args *desc; struct ast_tcptls_session_args *desc;

Loading…
Cancel
Save