comparison src/event/ngx_event_openssl.c @ 7870:fecf645ff2f8

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).
author Maxim Dounin <mdounin@mdounin.ru>
date Tue, 01 Jun 2021 17:37:49 +0300
parents 51e6a665523c
children 5f765427c17a
comparison
equal deleted inserted replaced
7869:d61d590ac826 7870:fecf645ff2f8
2894 2894
2895 ngx_int_t 2895 ngx_int_t
2896 ngx_ssl_shutdown(ngx_connection_t *c) 2896 ngx_ssl_shutdown(ngx_connection_t *c)
2897 { 2897 {
2898 int n, sslerr, mode; 2898 int n, sslerr, mode;
2899 ngx_int_t rc;
2899 ngx_err_t err; 2900 ngx_err_t err;
2900 ngx_uint_t tries; 2901 ngx_uint_t tries;
2902
2903 rc = NGX_OK;
2901 2904
2902 ngx_ssl_ocsp_cleanup(c); 2905 ngx_ssl_ocsp_cleanup(c);
2903 2906
2904 if (SSL_in_init(c->ssl->connection)) { 2907 if (SSL_in_init(c->ssl->connection)) {
2905 /* 2908 /*
2906 * OpenSSL 1.0.2f complains if SSL_shutdown() is called during 2909 * OpenSSL 1.0.2f complains if SSL_shutdown() is called during
2907 * an SSL handshake, while previous versions always return 0. 2910 * an SSL handshake, while previous versions always return 0.
2908 * Avoid calling SSL_shutdown() if handshake wasn't completed. 2911 * Avoid calling SSL_shutdown() if handshake wasn't completed.
2909 */ 2912 */
2910 2913
2911 SSL_free(c->ssl->connection); 2914 goto done;
2912 c->ssl = NULL;
2913 c->recv = ngx_recv;
2914
2915 return NGX_OK;
2916 } 2915 }
2917 2916
2918 if (c->timedout || c->error || c->buffered) { 2917 if (c->timedout || c->error || c->buffered) {
2919 mode = SSL_RECEIVED_SHUTDOWN|SSL_SENT_SHUTDOWN; 2918 mode = SSL_RECEIVED_SHUTDOWN|SSL_SENT_SHUTDOWN;
2920 SSL_set_quiet_shutdown(c->ssl->connection, 1); 2919 SSL_set_quiet_shutdown(c->ssl->connection, 1);
2952 n = SSL_shutdown(c->ssl->connection); 2951 n = SSL_shutdown(c->ssl->connection);
2953 2952
2954 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_shutdown: %d", n); 2953 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_shutdown: %d", n);
2955 2954
2956 if (n == 1) { 2955 if (n == 1) {
2957 SSL_free(c->ssl->connection); 2956 goto done;
2958 c->ssl = NULL;
2959 c->recv = ngx_recv;
2960
2961 return NGX_OK;
2962 } 2957 }
2963 2958
2964 if (n == 0 && tries-- > 1) { 2959 if (n == 0 && tries-- > 1) {
2965 continue; 2960 continue;
2966 } 2961 }
2982 } else { 2977 } else {
2983 c->write->ready = 0; 2978 c->write->ready = 0;
2984 } 2979 }
2985 2980
2986 if (ngx_handle_read_event(c->read, 0) != NGX_OK) { 2981 if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
2987 return NGX_ERROR; 2982 goto failed;
2988 } 2983 }
2989 2984
2990 if (ngx_handle_write_event(c->write, 0) != NGX_OK) { 2985 if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
2991 return NGX_ERROR; 2986 goto failed;
2992 } 2987 }
2993 2988
2994 ngx_add_timer(c->read, 3000); 2989 ngx_add_timer(c->read, 3000);
2995 2990
2996 return NGX_AGAIN; 2991 return NGX_AGAIN;
2997 } 2992 }
2998 2993
2999 if (sslerr == SSL_ERROR_ZERO_RETURN || ERR_peek_error() == 0) { 2994 if (sslerr == SSL_ERROR_ZERO_RETURN || ERR_peek_error() == 0) {
3000 SSL_free(c->ssl->connection); 2995 goto done;
3001 c->ssl = NULL;
3002 c->recv = ngx_recv;
3003
3004 return NGX_OK;
3005 } 2996 }
3006 2997
3007 err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0; 2998 err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0;
3008 2999
3009 ngx_ssl_connection_error(c, sslerr, err, "SSL_shutdown() failed"); 3000 ngx_ssl_connection_error(c, sslerr, err, "SSL_shutdown() failed");
3010 3001
3011 SSL_free(c->ssl->connection); 3002 break;
3012 c->ssl = NULL; 3003 }
3013 c->recv = ngx_recv; 3004
3014 3005 failed:
3015 return NGX_ERROR; 3006
3016 } 3007 rc = NGX_ERROR;
3008
3009 done:
3010
3011 SSL_free(c->ssl->connection);
3012 c->ssl = NULL;
3013 c->recv = ngx_recv;
3014
3015 return rc;
3017 } 3016 }
3018 3017
3019 3018
3020 static void 3019 static void
3021 ngx_ssl_shutdown_handler(ngx_event_t *ev) 3020 ngx_ssl_shutdown_handler(ngx_event_t *ev)