Opened 11 months ago
Last modified 7 months ago
#2585 closed defect
segfault in quic — at Version 1
Reported by: | Owned by: | ||
---|---|---|---|
Priority: | major | Milestone: | nginx-1.26 |
Component: | http/3 | Version: | 1.25.x |
Keywords: | segfault, quic | Cc: | |
uname -a: | Linux c-d050-u2651-40 5.15.0-40-lowlatency #43-Ubuntu SMP PREEMPT Thu Jun 16 17:07:13 UTC 2022 x86_64 x86_64 x86_64 GNU/L | ||
nginx -V: |
nginx version: nginx/1.25.4
built by gcc 11.2.0 (Ubuntu 11.2.0-19ubuntu1) built with OpenSSL 3.0.2 15 Mar 2022 TLS SNI support enabled configure arguments: --prefix=/cdn/nginx_quic --with-cc-opt='-O0 -g -ggdb -march=core2' --with-debug --with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -fPIC' --with-ipv6 --with-http_geoip_module --with-http_realip_module --with-http_ssl_module --without-http_charset_module --without-http_ssi_module --without-http_userid_module --without-http_autoindex_module --without-http_scgi_module --without-http_uwsgi_module --without-http_fastcgi_module --without-http_limit_conn_module --without-http_split_clients_module --without-http_limit_req_module --with-http_stub_status_module --with-http_v2_module --with-http_v3_module --with-http_slice_module --with-stream_ssl_module |
Description (last modified by )
warning: Can't open file /dev/zero (deleted) during file-backed mapping note processing
[New LWP 138846]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Core was generated by `nginx: worker process '.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x00007fcd4014a214 in EVP_CIPHER_CTX_is_encrypting () from /lib/x86_64-linux-gnu/libcrypto.so.3
(gdb) bt
#0 0x00007fcd4014a214 in EVP_CIPHER_CTX_is_encrypting () from /lib/x86_64-linux-gnu/libcrypto.so.3
#1 0x00005646ac29ff3f in ngx_quic_crypto_common (s=0x5646adeb3470, out=0x7ffd2593ad28, nonce=0x7ffd2593ab4c "", in=0x7ffd2593ab20, ad=0x7ffd2593ab30, log=0x5646af2d8100)
at src/event/quic/ngx_event_quic_protection.c:493
#2 0x00005646ac29fea3 in ngx_quic_crypto_open (s=0x5646adeb3470, out=0x7ffd2593ad28, nonce=0x7ffd2593ab4c "", in=0x7ffd2593ab20, ad=0x7ffd2593ab30, log=0x5646af2d8100)
at src/event/quic/ngx_event_quic_protection.c:458
#3 0x00005646ac2a1f09 in ngx_quic_decrypt (pkt=0x7ffd2593ac60, largest_pn=0x5646ae310a58) at src/event/quic/ngx_event_quic_protection.c:1190
#4 0x00005646ac298727 in ngx_quic_handle_payload (c=0x7fcd2fd48790, pkt=0x7ffd2593ac60) at src/event/quic/ngx_event_quic.c:982
#5 0x00005646ac29801f in ngx_quic_handle_packet (c=0x7fcd2fd48790, conf=0x0, pkt=0x7ffd2593ac60) at src/event/quic/ngx_event_quic.c:843
#6 0x00005646ac2979ab in ngx_quic_handle_datagram (c=0x7fcd2fd48790, b=0x7ffd2593ae90, conf=0x0) at src/event/quic/ngx_event_quic.c:693
#7 0x00005646ac296d31 in ngx_quic_input_handler (rev=0x7fcd2fb07310) at src/event/quic/ngx_event_quic.c:436
#8 0x00005646ac29a093 in ngx_quic_recvmsg (ev=0x7fcd2fb07070) at src/event/quic/ngx_event_quic_udp.c:195
#9 0x00005646ac2821f2 in ngx_epoll_process_events (cycle=0x5646add304c0, timer=98, flags=1) at src/event/modules/ngx_epoll_module.c:901
#10 0x00005646ac26e5b7 in ngx_process_events_and_timers (cycle=0x5646add304c0) at src/event/ngx_event.c:248
#11 0x00005646ac27f562 in ngx_worker_process_cycle (cycle=0x5646add304c0, data=0x1a) at src/os/unix/ngx_process_cycle.c:721
#12 0x00005646ac27ba5c in ngx_spawn_process (cycle=0x5646add304c0, proc=0x5646ac27f468 <ngx_worker_process_cycle>, data=0x1a, name=0x5646ac360c62 "worker process", respawn=-3) at src/os/unix/ngx_process.c:199
#13 0x00005646ac27e2bf in ngx_start_worker_processes (cycle=0x5646add304c0, n=48, type=-3) at src/os/unix/ngx_process_cycle.c:344
#14 0x00005646ac27d92e in ngx_master_process_cycle (cycle=0x5646add304c0) at src/os/unix/ngx_process_cycle.c:130
#15 0x00005646ac234ab0 in main (argc=1, argv=0x7ffd2593b718) at src/core/nginx.c:384
(gdb) d 1
No breakpoint number 1.
(gdb) f 1
#1 0x00005646ac29ff3f in ngx_quic_crypto_common (s=0x5646adeb3470, out=0x7ffd2593ad28, nonce=0x7ffd2593ab4c "", in=0x7ffd2593ab20, ad=0x7ffd2593ab30, log=0x5646af2d8100)
at src/event/quic/ngx_event_quic_protection.c:493
warning: Source file is more recent than executable.
493 enc = EVP_CIPHER_CTX_encrypting(ctx);
(gdb) p ctx
$1 = (EVP_CIPHER_CTX *) 0x0
(gdb) f 2
#2 0x00005646ac29fea3 in ngx_quic_crypto_open (s=0x5646adeb3470, out=0x7ffd2593ad28, nonce=0x7ffd2593ab4c "", in=0x7ffd2593ab20, ad=0x7ffd2593ab30, log=0x5646af2d8100)
at src/event/quic/ngx_event_quic_protection.c:458
458 return ngx_quic_crypto_common(s, out, nonce, in, ad, log);
(gdb) p s
$2 = (ngx_quic_secret_t *) 0x5646adeb3470
(gdb) p *s
$3 = {secret = {len = 0, data = '\000' <repeats 47 times>}, iv = {len = 0, data = '\000' <repeats 11 times>}, hp = {len = 0, data = '\000' <repeats 47 times>}, ctx = 0x0, hp_ctx = 0x0}
(gdb) f 3
#3 0x00005646ac2a1f09 in ngx_quic_decrypt (pkt=0x7ffd2593ac60, largest_pn=0x5646ae310a58) at src/event/quic/ngx_event_quic_protection.c:1190
1190 if (ngx_quic_crypto_open(secret, &pkt->payload, nonce, &in, &ad, pkt->log)
(gdb) p secret->ctx
$4 = (EVP_CIPHER_CTX *) 0x0
(gdb) p *secret
$5 = {secret = {len = 0, data = '\000' <repeats 47 times>}, iv = {len = 0, data = '\000' <repeats 11 times>}, hp = {len = 0, data = '\000' <repeats 47 times>}, ctx = 0x0, hp_ctx = 0x0}
(gdb)
(gdb) p *secret
$5 = {secret = {len = 0, data = '\000' <repeats 47 times>}, iv = {len = 0, data = '\000' <repeats 11 times>}, hp = {len = 0, data = '\000' <repeats 47 times>}, ctx = 0x0, hp_ctx = 0x0}
(gdb) p pkt->keys->secrets[pkt->level].client
$6 = {secret = {len = 32, data = "\253\354ѫV\006\220\355Qa\221\334\324\377>=\027\273\016z\177\277Q4\025\n\225\026a\262\066\263", '\000' <repeats 15 times>}, iv = {len = 12,
data = "\224h5\025C\265\066\357E\253rZ"}, hp = {len = 16, data = "&P\314ԏ혎X\275\071\222\300\356Ӓ", '\000' <repeats 31 times>}, ctx = 0x5646adea0970, hp_ctx = 0x5646af284220}
(gdb) p pkt->keys->secrets[pkt->level].client->ctx
$7 = (EVP_CIPHER_CTX *) 0x5646adea0970
(gdb) p pkt->keys->next_key.client
$9 = {secret = {len = 0, data = '\000' <repeats 47 times>}, iv = {len = 0, data = '\000' <repeats 11 times>}, hp = {len = 0, data = '\000' <repeats 47 times>}, ctx = 0x0, hp_ctx = 0x0}
(gdb) p/t pkt->flags
$12 = 1111101
(gdb)
(gdb) p key_phase
$13 = 1
(gdb) p pkt->key_phase
$14 = 0
(gdb)
Looking at the backtrace, I saw problem appears in ngx_quic_crypto_common trying to call EVP_CIPHER_CTX_encrypting(ctx) with ctx pointing to NULL.
Tracing back through ngx_quic_crypto_common(), ngx_quic_crypto_open(), way don to ngx_quic_decrypt() we can see that this i actually secret->ctx is NULL.
Further we see that secret is taken from pkt->keys->secrets[pkt->level].client (line 1115 in ngx_quic_decrypt()) where ctx is has non zero value = 0x5646adea0970, but on line 1147
it overriden by secret = &pkt->keys->next_key.client; which has cts NULL. So it seems that key is about to be updated, but pkt->keys->next_key is to zero initialized structure.
I see that this could happen in ngx_quic_keys_switch() and ngx_quic_keys_cleanup(), so probably some wrong sequence makes worker to crash. I'm not yet so familiar yet with quic protocol
and its nginx implementation.
Change History (2)
by , 11 months ago
Attachment: | nginx.conf added |
---|
comment:1 by , 11 months ago
Description: | modified (diff) |
---|
Thanks for reporting this. We are looking into this issue now.
If you can post (or send directly to arut@…) the debug log, it would help a lot.
example configuration identical to real one, where the problem appeared