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).
This commit is contained in:
Maxim Dounin 2021-06-01 17:37:49 +03:00
parent df1da673f7
commit 235d2df1de

View File

@ -2896,9 +2896,12 @@ ngx_int_t
ngx_ssl_shutdown(ngx_connection_t *c) ngx_ssl_shutdown(ngx_connection_t *c)
{ {
int n, sslerr, mode; int n, sslerr, mode;
ngx_int_t rc;
ngx_err_t err; ngx_err_t err;
ngx_uint_t tries; ngx_uint_t tries;
rc = NGX_OK;
ngx_ssl_ocsp_cleanup(c); ngx_ssl_ocsp_cleanup(c);
if (SSL_in_init(c->ssl->connection)) { 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. * Avoid calling SSL_shutdown() if handshake wasn't completed.
*/ */
SSL_free(c->ssl->connection); goto done;
c->ssl = NULL;
c->recv = ngx_recv;
return NGX_OK;
} }
if (c->timedout || c->error || c->buffered) { 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); ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_shutdown: %d", n);
if (n == 1) { if (n == 1) {
SSL_free(c->ssl->connection); goto done;
c->ssl = NULL;
c->recv = ngx_recv;
return NGX_OK;
} }
if (n == 0 && tries-- > 1) { 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) { 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) { if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
return NGX_ERROR; goto failed;
} }
ngx_add_timer(c->read, 3000); 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) { if (sslerr == SSL_ERROR_ZERO_RETURN || ERR_peek_error() == 0) {
SSL_free(c->ssl->connection); goto done;
c->ssl = NULL;
c->recv = ngx_recv;
return NGX_OK;
} }
err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0; err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0;
ngx_ssl_connection_error(c, sslerr, err, "SSL_shutdown() failed"); ngx_ssl_connection_error(c, sslerr, err, "SSL_shutdown() failed");
SSL_free(c->ssl->connection); break;
c->ssl = NULL;
c->recv = ngx_recv;
return NGX_ERROR;
} }
failed:
rc = NGX_ERROR;
done:
SSL_free(c->ssl->connection);
c->ssl = NULL;
c->recv = ngx_recv;
return rc;
} }