diff options
author | Maxim Dounin <mdounin@mdounin.ru> | 2021-06-01 17:37:49 +0300 |
---|---|---|
committer | Maxim Dounin <mdounin@mdounin.ru> | 2021-06-01 17:37:49 +0300 |
commit | 235d2df1de6aba77db3d128c0c637c9d2e9a9d12 (patch) | |
tree | cc3cb8f9b3f96dd064b0b2408ef4801efbaf7834 | |
parent | df1da673f74f52c215a3e9eee2b99a28085e5baa (diff) | |
download | nginx-235d2df1de6aba77db3d128c0c637c9d2e9a9d12.tar.gz nginx-235d2df1de6aba77db3d128c0c637c9d2e9a9d12.zip |
SSL: ngx_ssl_shutdown() rework.
Instead of calling SSL_free() with each return point, introduced a single
place where cleanup happens. As a positive side effect, this fixes two
potential memory leaks on ngx_handle_read_event() and ngx_handle_write_event()
errors where there were no SSL_free() calls (though unlikely practical,
as errors there are only expected to happen due to bugs or kernel issues).
-rw-r--r-- | src/event/ngx_event_openssl.c | 43 |
1 files changed, 21 insertions, 22 deletions
diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c index d762d6b7f..06357834c 100644 --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -2896,9 +2896,12 @@ ngx_int_t ngx_ssl_shutdown(ngx_connection_t *c) { int n, sslerr, mode; + ngx_int_t rc; ngx_err_t err; ngx_uint_t tries; + rc = NGX_OK; + ngx_ssl_ocsp_cleanup(c); if (SSL_in_init(c->ssl->connection)) { @@ -2908,11 +2911,7 @@ ngx_ssl_shutdown(ngx_connection_t *c) * Avoid calling SSL_shutdown() if handshake wasn't completed. */ - SSL_free(c->ssl->connection); - c->ssl = NULL; - c->recv = ngx_recv; - - return NGX_OK; + goto done; } if (c->timedout || c->error || c->buffered) { @@ -2954,11 +2953,7 @@ ngx_ssl_shutdown(ngx_connection_t *c) ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_shutdown: %d", n); if (n == 1) { - SSL_free(c->ssl->connection); - c->ssl = NULL; - c->recv = ngx_recv; - - return NGX_OK; + goto done; } if (n == 0 && tries-- > 1) { @@ -2984,11 +2979,11 @@ ngx_ssl_shutdown(ngx_connection_t *c) } if (ngx_handle_read_event(c->read, 0) != NGX_OK) { - return NGX_ERROR; + goto failed; } if (ngx_handle_write_event(c->write, 0) != NGX_OK) { - return NGX_ERROR; + goto failed; } ngx_add_timer(c->read, 3000); @@ -2997,23 +2992,27 @@ ngx_ssl_shutdown(ngx_connection_t *c) } if (sslerr == SSL_ERROR_ZERO_RETURN || ERR_peek_error() == 0) { - SSL_free(c->ssl->connection); - c->ssl = NULL; - c->recv = ngx_recv; - - return NGX_OK; + goto done; } err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0; ngx_ssl_connection_error(c, sslerr, err, "SSL_shutdown() failed"); - SSL_free(c->ssl->connection); - c->ssl = NULL; - c->recv = ngx_recv; - - return NGX_ERROR; + break; } + +failed: + + rc = NGX_ERROR; + +done: + + SSL_free(c->ssl->connection); + c->ssl = NULL; + c->recv = ngx_recv; + + return rc; } |