Opened 6 years ago

Closed 6 years ago

Last modified 6 years ago

#1464 closed defect (fixed)

Segfault

Reported by: craveica@… Owned by: Sergey Kandaurov <pluknet@…>
Priority: minor Milestone:
Component: other Version: 1.13.x
Keywords: Cc:
uname -a: Linux dev-centos 3.10.0 #1 SMP Mon Jan 15 17:21:53 MSK 2018 x86_64 x86_64 x86_64 GNU/Linux
nginx -V: nginx version: openresty/1.13.6.1
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-11) (GCC)
built with OpenSSL 1.0.2k 26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/usr/local/openresty/nginx --with-cc-opt='-O2 -DNGX_LUA_ABORT_AT_PANIC -I/usr/local/openresty/zlib/include -I/usr/local/openresty/pcre/include -I/usr/local/openresty/openssl/include' --add-module=../ngx_devel_kit-0.3.0 --add-module=../echo-nginx-module-0.61 --add-module=../xss-nginx-module-0.05 --add-module=../ngx_coolkit-0.2rc3 --add-module=../set-misc-nginx-module-0.31 --add-module=../form-input-nginx-module-0.12 --add-module=../encrypted-session-nginx-module-0.07 --add-module=../srcache-nginx-module-0.31 --add-module=../ngx_lua-0.10.11 --add-module=../ngx_lua_upstream-0.07 --add-module=../headers-more-nginx-module-0.33 --add-module=../array-var-nginx-module-0.05 --add-module=../memc-nginx-module-0.18 --add-module=../redis2-nginx-module-0.14 --add-module=../redis-nginx-module-0.3.7 --add-module=../ngx_stream_lua-0.0.3 --with-ld-opt='-Wl,-rpath,/usr/local/openresty/luajit/lib -L/usr/local/openresty/zlib/lib -L/usr/local/openresty/pcre/lib -L/usr/local/openresty/openssl/lib -Wl,-rpath,/usr/local/openresty/zlib/lib:/usr/local/openresty/pcre/lib:/usr/local/openresty/openssl/lib' --with-pcre-jit --with-stream --with-stream_ssl_module --with-http_v2_module --without-mail_pop3_module --without-mail_imap_module --without-mail_smtp_module --with-http_stub_status_module --with-http_realip_module --with-http_addition_module --with-http_auth_request_module --with-http_secure_link_module --with-http_random_index_module --with-http_gzip_static_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-threads --with-file-aio --with-dtrace-probes --with-stream --with-stream_ssl_module --with-http_ssl_module

Description

Nginx will crash using this minimal config:

worker_processes 1;
error_log logs/error.log debug;
worker_rlimit_core 500M;
working_directory /tmp;
events {}
http {
    ssl_client_certificate origin-pull-ca.pem;
    ssl_verify_client on;
    server {
        listen 443 default_server ssl;
        server_name _;
        ssl_certificate      cert.pem;
        ssl_certificate_key  cert.key;
    }

    server {
        listen 443;
        server_name example.com;
    }
}

curl -k https://example.com

Backtrace:

Core was generated by `nginx: worker process                                                         '.
Program terminated with signal 11, Segmentation fault.
#0  remove_session_lock (lck=<optimized out>, c=<optimized out>, ctx=<optimized out>) at ssl_sess.c:845
845	        if ((r = lh_SSL_SESSION_retrieve(ctx->sessions, c)) == c) {
(gdb) bt
#0  remove_session_lock (lck=<optimized out>, c=<optimized out>, ctx=<optimized out>) at ssl_sess.c:845
#1  SSL_CTX_remove_session (ctx=ctx@entry=0x0, c=c@entry=0x8ccbc0) at ssl_sess.c:834
#2  0x000000000044c0a1 in ngx_ssl_remove_cached_session (ssl=0x0, sess=0x8ccbc0) at src/event/ngx_event_openssl.c:2721
#3  0x000000000045d014 in ngx_http_process_request (r=0x9229d0) at src/http/ngx_http_request.c:1921
#4  0x000000000045d70b in ngx_http_process_request_line (rev=0x90aa20) at src/http/ngx_http_request.c:1049
#5  0x0000000000446ab7 in ngx_epoll_process_events (cycle=<optimized out>, timer=<optimized out>, flags=<optimized out>) at src/event/modules/ngx_epoll_module.c:902
#6  0x000000000043df3b in ngx_process_events_and_timers (cycle=cycle@entry=0x8bd4c0) at src/event/ngx_event.c:252
#7  0x00000000004449d2 in ngx_worker_process_cycle (cycle=cycle@entry=0x8bd4c0, data=data@entry=0x0) at src/os/unix/ngx_process_cycle.c:815
#8  0x00000000004434b4 in ngx_spawn_process (cycle=cycle@entry=0x8bd4c0, proc=proc@entry=0x444960 <ngx_worker_process_cycle>, data=data@entry=0x0, 
    name=name@entry=0x542645 "worker process", respawn=respawn@entry=-3) at src/os/unix/ngx_process.c:198
#9  0x0000000000444e34 in ngx_start_worker_processes (cycle=cycle@entry=0x8bd4c0, n=1, type=type@entry=-3) at src/os/unix/ngx_process_cycle.c:396
#10 0x0000000000445748 in ngx_master_process_cycle (cycle=cycle@entry=0x8bd4c0) at src/os/unix/ngx_process_cycle.c:135
#11 0x000000000041f162 in main (argc=<optimized out>, argv=<optimized out>) at src/core/nginx.c:381
(gdb) quit

For more information please see my original issue I've posted to openresty:
https://github.com/openresty/openresty/issues/333

Thank you.

Change History (7)

comment:1 by craveica@…, 6 years ago

It looks like the missing certificate from a virtual server block is causing the crash.

comment:2 by craveica@…, 6 years ago

Probably duplicate of #178

comment:3 by Sergey Kandaurov, 6 years ago

Status: newaccepted

It is generally advised to specify the ssl_certificate/ssl_certificate_key pair in all server blocks that contain the listen ... ssl directive so that the SSL context is always present. Otherwise, bad things could happen in various unexpected ways.

For the reported issue, please try this patch.

# HG changeset patch
# User Sergey Kandaurov <pluknet@nginx.com>
# Date 1516640791 -10800
#      Mon Jan 22 20:06:31 2018 +0300
# Node ID 9c1de3f91dd43ebdc7c16f8faf5b209a3fcb1af7
# Parent  93abb5a855d6534f0356882f45be49f8c6a95a8b
SSL: using default server context in session remove (ticket #1464).

This fixes runtime in configurations with multiple virtual servers sharing
the same port, where a non-default virtual server block misses certificate.

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
@@ -1902,7 +1902,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);
@@ -1916,7 +1916,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);
diff --git a/src/mail/ngx_mail_handler.c b/src/mail/ngx_mail_handler.c
--- a/src/mail/ngx_mail_handler.c
+++ b/src/mail/ngx_mail_handler.c
@@ -302,7 +302,7 @@ ngx_mail_verify_cert(ngx_mail_session_t 
                       "client SSL certificate verify error: (%l:%s)",
                       rc, X509_verify_cert_error_string(rc));
 
-        ngx_ssl_remove_cached_session(sslcf->ssl.ctx,
+        ngx_ssl_remove_cached_session(c->ssl->session_ctx,
                                       (SSL_get0_session(c->ssl->connection)));
 
         cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
@@ -323,7 +323,7 @@ ngx_mail_verify_cert(ngx_mail_session_t 
             ngx_log_error(NGX_LOG_INFO, c->log, 0,
                           "client sent no required SSL certificate");
 
-            ngx_ssl_remove_cached_session(sslcf->ssl.ctx,
+            ngx_ssl_remove_cached_session(c->ssl->session_ctx,
                                        (SSL_get0_session(c->ssl->connection)));
 
             cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
diff --git a/src/stream/ngx_stream_ssl_module.c b/src/stream/ngx_stream_ssl_module.c
--- a/src/stream/ngx_stream_ssl_module.c
+++ b/src/stream/ngx_stream_ssl_module.c
@@ -328,7 +328,7 @@ ngx_stream_ssl_handler(ngx_stream_sessio
                           "client SSL certificate verify error: (%l:%s)",
                           rc, X509_verify_cert_error_string(rc));
 
-            ngx_ssl_remove_cached_session(sslcf->ssl.ctx,
+            ngx_ssl_remove_cached_session(c->ssl->session_ctx,
                                        (SSL_get0_session(c->ssl->connection)));
             return NGX_ERROR;
         }
@@ -340,7 +340,7 @@ ngx_stream_ssl_handler(ngx_stream_sessio
                 ngx_log_error(NGX_LOG_INFO, c->log, 0,
                               "client sent no required SSL certificate");
 
-                ngx_ssl_remove_cached_session(sslcf->ssl.ctx,
+                ngx_ssl_remove_cached_session(c->ssl->session_ctx,
                                        (SSL_get0_session(c->ssl->connection)));
                 return NGX_ERROR;
             }

comment:4 by craveica@…, 6 years ago

It's working very well. Thank you!

comment:5 by Sergey Kandaurov <pluknet@…>, 6 years ago

Owner: set to Sergey Kandaurov <pluknet@…>
Resolution: fixed
Status: acceptedclosed

In 7193:9d14931cec8c/nginx:

SSL: using default server context in session remove (closes #1464).

This fixes segfault in configurations with multiple virtual servers sharing
the same port, where a non-default virtual server block misses certificate.

comment:6 by Sergey Kandaurov <pluknet@…>, 6 years ago

In 1277:1d7c87dba788/nginx-tests:

Tests: added test for SSL session remove (ticket #1464).

comment:7 by Sergey Kandaurov, 6 years ago

See also #1585.

Note: See TracTickets for help on using tickets.