[nginx] SSL: ngx_ssl_shutdown() rework.

Maxim Dounin mdounin at mdounin.ru
Tue Jun 1 14:42:52 UTC 2021


details:   https://hg.nginx.org/nginx/rev/fecf645ff2f8
branches:  
changeset: 7870:fecf645ff2f8
user:      Maxim Dounin <mdounin at mdounin.ru>
date:      Tue Jun 01 17:37:49 2021 +0300
description:
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).

diffstat:

 src/event/ngx_event_openssl.c |  45 +++++++++++++++++++++---------------------
 1 files changed, 22 insertions(+), 23 deletions(-)

diffs (95 lines):

diff -r d61d590ac826 -r fecf645ff2f8 src/event/ngx_event_openssl.c
--- a/src/event/ngx_event_openssl.c	Sun May 30 12:26:00 2021 +0300
+++ b/src/event/ngx_event_openssl.c	Tue Jun 01 17:37:49 2021 +0300
@@ -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;
 }
 
 


More information about the nginx-devel mailing list