nginx ssl_verify_client on leads to segmentation fault

Maxim Dounin mdounin at mdounin.ru
Mon May 15 16:20:09 UTC 2017


Hello!

On Mon, May 15, 2017 at 08:16:38AM +0200, Thomas Glanzmann wrote:

> Hello,
> I'm running nginx from git HEAD, when I add the following two lines to a
> https server:
> 
> ssl_client_certificate /tmp/ca.crt;
> ssl_verify_client on;
> 
> and connect to the website, I get:
> 
> 2017/05/15 08:12:04 [alert] 9109#0: worker process 12908 exited on signal 11 (core dumped)
> 2017/05/15 08:12:04 [alert] 9109#0: worker process 12909 exited on signal 11 (core dumped)
> 2017/05/15 08:12:10 [alert] 9109#0: worker process 12916 exited on signal 11 (core dumped)

[...]

> (gdb) bt
> #0  0x00007fbd9b8653db in ?? () from /usr/lib/x86_64-linux-gnu/libssl.so.1.0.0
> #1  0x00007fbd9c5c2a16 in ngx_ssl_remove_cached_session (ssl=0x0, sess=0x7fbd9eb7ccf0) at src/event/ngx_event_openssl.c:2698
> #2  0x00007fbd9c5d3633 in ngx_http_process_request (r=r at entry=0x7fbd9e67d6b0) at src/http/ngx_http_request.c:1902

Could you please confirm you do _not_ have ssl_certificate defined 
in the server block where you've added ssl_verify_client?

I was able to reproduce the problem with the following 
configuration:

    server{
        listen 8443 ssl;

        ssl_certificate test.crt;
        ssl_certificate_key test.key;
    }

    server {
        listen 8443 ssl;
        server_name foo;

        ssl_verify_client on;
        ssl_client_certificate test.root;
    }

(Just in case, an obvious workaround would be to add 
ssl_certificate to the second server.)

Here is a patch:

# HG changeset patch
# User Maxim Dounin <mdounin at mdounin.ru>
# Date 1494865081 -10800
#      Mon May 15 19:18:01 2017 +0300
# Node ID 26c5ec160d3cb89ec681c285a3d87cae0595cb9e
# Parent  c85782291153482fe126e20ebc13b30eca4139ee
SSL: fixed context when removing cached sessions.

When removing cached session due to client certificate verification failure,
we have to use c->ssl->session_ctx, which matches the SSL context used by
OpenSSL when reusing sessions (see 97f102a13f33).

Using a context from currently selected virtual server is wrong, as it may
be different from the session context.  Moreover, it may be NULL if there is
no certificate defined in the currently selected virtual server, leading
to a segmentation fault.

Reported by Thomas Glanzmann.

diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -1885,7 +1885,7 @@ ngx_http_process_request(ngx_http_reques
                               "client SSL certificate verify error: (%l:%s)",
                               rc, X509_verify_cert_error_string(rc));
 
-                ngx_ssl_remove_cached_session(sscf->ssl.ctx,
+                ngx_ssl_remove_cached_session(c->ssl->session_ctx,
                                        (SSL_get0_session(c->ssl->connection)));
 
                 ngx_http_finalize_request(r, NGX_HTTPS_CERT_ERROR);
@@ -1899,7 +1899,7 @@ ngx_http_process_request(ngx_http_reques
                     ngx_log_error(NGX_LOG_INFO, c->log, 0,
                                   "client sent no required SSL certificate");
 
-                    ngx_ssl_remove_cached_session(sscf->ssl.ctx,
+                    ngx_ssl_remove_cached_session(c->ssl->session_ctx,
                                        (SSL_get0_session(c->ssl->connection)));
 
                     ngx_http_finalize_request(r, NGX_HTTPS_NO_CERT);

-- 
Maxim Dounin
http://nginx.org/


More information about the nginx mailing list