Resolve memory leaks in TLS initialization and TLS client connections

This patch resolves two sources of memory leaks when using TLS in Asterisk:
1) It removes improper initialization (and multiple re-initializations) of
   portions of the SSL library.  Asterisk calls SSL_library_init and
   SSL_load_error_strings during SSL initialization; collectively this
   obviates the need for calling any of the following during initialization
   or client connection handling:
   * ERR_load_crypto_strings (handled by SSL_load_error_strings)
   * OpenSSL_add_all_algorithms (synonym for SSL_library_init)
   * SSLeay_add_ssl_algorithms (synonym for SSL_library_init)
2) Failure to completely clean up all memory allocated by Asterisk and by
   the SSL library for TLS clients.  This included not freeing the SSL_CTX
   object in the SIP channel driver, as well as not clearing the error
   stack when the TLS client exited.

Note that these memory leaks were found by Thomas Arimont, and this patch
was essentially written by him with some minor tweaks.

(closes issue AST-889)
Reported by: Thomas Arimont
Tested by: Thomas Arimont
patches:
  (bugAST-889.patch) by Thomas Arimont (license 5525)

Review: https://reviewboard.asterisk.org/r/2105
........

Merged revisions 373061 from http://svn.asterisk.org/svn/asterisk/branches/1.8
........

Merged revisions 373062 from http://svn.asterisk.org/svn/asterisk/branches/10
........

Merged revisions 373079 from http://svn.asterisk.org/svn/asterisk/branches/11


git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@373080 65c4cc65-6c06-0410-ace0-fbb531ad65f3
changes/78/78/1
Matthew Jordan 13 years ago
parent f97510b730
commit f92bb6265c

@ -2451,6 +2451,8 @@ static void sip_tcptls_client_args_destructor(void *obj)
ast_free(args->tls_cfg->cipher); ast_free(args->tls_cfg->cipher);
ast_free(args->tls_cfg->cafile); ast_free(args->tls_cfg->cafile);
ast_free(args->tls_cfg->capath); ast_free(args->tls_cfg->capath);
ast_ssl_teardown(args->tls_cfg);
} }
ast_free(args->tls_cfg); ast_free(args->tls_cfg);
ast_free((char *) args->name); ast_free((char *) args->name);

@ -158,7 +158,6 @@ int ast_ssl_init(void)
void (*real_CRYPTO_set_locking_callback)(void (*)(int, int, const char *, int)); void (*real_CRYPTO_set_locking_callback)(void (*)(int, int, const char *, int));
void (*real_SSL_load_error_strings)(void); void (*real_SSL_load_error_strings)(void);
void (*real_ERR_load_SSL_strings)(void); void (*real_ERR_load_SSL_strings)(void);
void (*real_ERR_load_crypto_strings)(void);
void (*real_ERR_load_BIO_strings)(void); void (*real_ERR_load_BIO_strings)(void);
const char *errstr; const char *errstr;
@ -220,17 +219,9 @@ int ast_ssl_init(void)
get_OpenSSL_function(ERR_load_SSL_strings); get_OpenSSL_function(ERR_load_SSL_strings);
real_ERR_load_SSL_strings(); real_ERR_load_SSL_strings();
get_OpenSSL_function(ERR_load_crypto_strings);
real_ERR_load_crypto_strings();
get_OpenSSL_function(ERR_load_BIO_strings); get_OpenSSL_function(ERR_load_BIO_strings);
real_ERR_load_BIO_strings(); real_ERR_load_BIO_strings();
#if 0
/* currently this is just another call to SSL_library_init, so we don't call it */
OpenSSL_add_all_algorithms();
#endif
startup_complete = 1; startup_complete = 1;
#endif /* HAVE_OPENSSL */ #endif /* HAVE_OPENSSL */

@ -84,6 +84,7 @@ static int ssl_close(void *cookie)
{ {
int cookie_fd = SSL_get_fd(cookie); int cookie_fd = SSL_get_fd(cookie);
int ret; int ret;
if (cookie_fd > -1) { if (cookie_fd > -1) {
/* /*
* According to the TLS standard, it is acceptable for an application to only send its shutdown * According to the TLS standard, it is acceptable for an application to only send its shutdown
@ -93,6 +94,12 @@ static int ssl_close(void *cookie)
if ((ret = SSL_shutdown(cookie)) < 0) { if ((ret = SSL_shutdown(cookie)) < 0) {
ast_log(LOG_ERROR, "SSL_shutdown() failed: %d\n", SSL_get_error(cookie, ret)); ast_log(LOG_ERROR, "SSL_shutdown() failed: %d\n", SSL_get_error(cookie, ret));
} }
if (!((SSL*)cookie)->server) {
/* For client threads, ensure that the error stack is cleared */
ERR_remove_state(0);
}
SSL_free(cookie); SSL_free(cookie);
/* adding shutdown(2) here has no added benefit */ /* adding shutdown(2) here has no added benefit */
if (close(cookie_fd)) { if (close(cookie_fd)) {
@ -320,9 +327,6 @@ static int __ssl_setup(struct ast_tls_config *cfg, int client)
return 0; return 0;
} }
SSL_load_error_strings();
SSLeay_add_ssl_algorithms();
/* Get rid of an old SSL_CTX since we're about to /* Get rid of an old SSL_CTX since we're about to
* allocate a new one * allocate a new one
*/ */
@ -364,7 +368,6 @@ static int __ssl_setup(struct ast_tls_config *cfg, int client)
if (!client) { if (!client) {
/* Clients don't need a certificate, but if its setup we can use it */ /* Clients don't need a certificate, but if its setup we can use it */
ast_verb(0, "SSL error loading cert file. <%s>\n", cfg->certfile); ast_verb(0, "SSL error loading cert file. <%s>\n", cfg->certfile);
sleep(2);
cfg->enabled = 0; cfg->enabled = 0;
SSL_CTX_free(cfg->ssl_ctx); SSL_CTX_free(cfg->ssl_ctx);
cfg->ssl_ctx = NULL; cfg->ssl_ctx = NULL;
@ -375,7 +378,6 @@ static int __ssl_setup(struct ast_tls_config *cfg, int client)
if (!client) { if (!client) {
/* Clients don't need a private key, but if its setup we can use it */ /* Clients don't need a private key, but if its setup we can use it */
ast_verb(0, "SSL error loading private key file. <%s>\n", tmpprivate); ast_verb(0, "SSL error loading private key file. <%s>\n", tmpprivate);
sleep(2);
cfg->enabled = 0; cfg->enabled = 0;
SSL_CTX_free(cfg->ssl_ctx); SSL_CTX_free(cfg->ssl_ctx);
cfg->ssl_ctx = NULL; cfg->ssl_ctx = NULL;
@ -387,7 +389,6 @@ static int __ssl_setup(struct ast_tls_config *cfg, int client)
if (SSL_CTX_set_cipher_list(cfg->ssl_ctx, cfg->cipher) == 0 ) { if (SSL_CTX_set_cipher_list(cfg->ssl_ctx, cfg->cipher) == 0 ) {
if (!client) { if (!client) {
ast_verb(0, "SSL cipher error <%s>\n", cfg->cipher); ast_verb(0, "SSL cipher error <%s>\n", cfg->cipher);
sleep(2);
cfg->enabled = 0; cfg->enabled = 0;
SSL_CTX_free(cfg->ssl_ctx); SSL_CTX_free(cfg->ssl_ctx);
cfg->ssl_ctx = NULL; cfg->ssl_ctx = NULL;

Loading…
Cancel
Save