Mercurial > hg > nginx
comparison src/event/ngx_event_openssl.c @ 7955:0601a4e793bf stable-1.20
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
7954:e9a98fb95c48 | 7955:0601a4e793bf |
---|---|
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) |