mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2024-12-22 12:30:07 +00:00
BUG/MAJOR: quic: Crash with TLS_AES_128_CCM_SHA256 (libressl only)
At least 3.9.0 version of libressl TLS stack does not behave as others stacks like quictls which make SSL_do_handshake() return an error when no cipher could be negotiated in addition to emit a TLS alert(0x28). This is the case when TLS_AES_128_CCM_SHA256 is forced as TLS1.3 cipher from the client side. This make haproxy enter a code path which leads to a crash as follows: [Switching to Thread 0x7ffff76b9640 (LWP 23902)] 0x0000000000487627 in quic_tls_key_update (qc=qc@entry=0x7ffff00371f0) at src/quic_tls.c:910 910 struct quic_kp_trace kp_trace = { (gdb) list 905 { 906 struct quic_tls_ctx *tls_ctx = &qc->ael->tls_ctx; 907 struct quic_tls_secrets *rx = &tls_ctx->rx; 908 struct quic_tls_secrets *tx = &tls_ctx->tx; 909 /* Used only for the traces */ 910 struct quic_kp_trace kp_trace = { 911 .rx_sec = rx->secret, 912 .rx_seclen = rx->secretlen, 913 .tx_sec = tx->secret, 914 .tx_seclen = tx->secretlen, (gdb) p qc $1 = (struct quic_conn *) 0x7ffff00371f0 (gdb) p qc->ael $2 = (struct quic_enc_level *) 0x0 (gdb) bt #0 0x0000000000487627 in quic_tls_key_update (qc=qc@entry=0x7ffff00371f0) at src/quic_tls.c:910 #1 0x000000000049bca9 in qc_ssl_provide_quic_data (len=268, data=<optimized out>, ctx=0x7ffff0047f80, level=<optimized out>, ncbuf=<optimized out>) at src/quic_ssl.c:617 #2 qc_ssl_provide_all_quic_data (qc=qc@entry=0x7ffff00371f0, ctx=0x7ffff0047f80) at src/quic_ssl.c:688 #3 0x00000000004683a7 in quic_conn_io_cb (t=0x7ffff0047f30, context=0x7ffff00371f0, state=<optimized out>) at src/quic_conn.c:760 #4 0x000000000063cd9c in run_tasks_from_lists (budgets=budgets@entry=0x7ffff76961f0) at src/task.c:596 #5 0x000000000063d934 in process_runnable_tasks () at src/task.c:876 #6 0x0000000000600508 in run_poll_loop () at src/haproxy.c:3073 #7 0x0000000000600b67 in run_thread_poll_loop (data=<optimized out>) at src/haproxy.c:3287 #8 0x00007ffff7f6ae45 in start_thread () from /lib64/libpthread.so.0 #9 0x00007ffff78254af in clone () from /lib64/libc.so.6 When a TLS alert is emitted, haproxy calls quic_set_connection_close() which sets QUIC_FL_CONN_IMMEDIATE_CLOSE connection flag. This is this flag which is tested by this patch to make the handshake fail even if SSL_do_handshake() does not return an error. This test is specific to libressl and never run with others TLS stack. Thank you to @lgv5 and @botovq for having reported this issue in GH #2569. Must be backported as far as 2.6.
This commit is contained in:
parent
0e93549d2a
commit
169fc0b771
@ -557,6 +557,17 @@ static int qc_ssl_provide_quic_data(struct ncbuf *ncbuf,
|
||||
ERR_clear_error();
|
||||
goto leave;
|
||||
}
|
||||
#if defined(LIBRESSL_VERSION_NUMBER)
|
||||
else if (qc->flags & QUIC_FL_CONN_IMMEDIATE_CLOSE) {
|
||||
/* Some libressl versions emit TLS alerts without making the handshake
|
||||
* (SSL_do_handshake()) fail. This is at least the case for
|
||||
* libressl-3.9.0 when forcing the TLS cipher to TLS_AES_128_CCM_SHA256.
|
||||
*/
|
||||
TRACE_ERROR("SSL handshake error", QUIC_EV_CONN_IO_CB, qc, &state, &ssl_err);
|
||||
HA_ATOMIC_INC(&qc->prx_counters->hdshk_fail);
|
||||
goto leave;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(OPENSSL_IS_AWSLC)
|
||||
/* As a server, if early data is accepted, SSL_do_handshake will
|
||||
|
Loading…
Reference in New Issue
Block a user