From f4bec87d4a76eebc1c1eaec3a980a01103e05309 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= Date: Mon, 20 Nov 2023 16:54:57 +0100 Subject: [PATCH] BUG/MEDIUM: quic: Possible crash for connections to be killed The connections are flagged as "to be killed" asap when the peer has left (detected by sendto() "Connection refused" errno) by qc_kill_conn(). This function has to wakeup the idle timer task to release the connection (and the idle timer and the idle timer task itself). Then if in the meantime the connection was flagged as having to process some retransmissions, some packet could lead to sendto() errors again with a call to qc_kill_conn(), this time with a released idle timer task. This bug could be detected by libasan as follows: .AddressSanitizer:DEADLYSIGNAL ================================================================= ==21018==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x 560b5d898717 bp 0x7f9aaac30000 sp 0x7f9aaac2ff80 T3) ==21018==The signal is caused by a READ memory access. ==21018==Hint: address points to the zero page. . #0 0x560b5d898717 in _task_wakeup include/haproxy/task.h:209 #1 0x560b5d8a563c in qc_kill_conn src/quic_conn.c:171 #2 0x560b5d97f832 in qc_send_ppkts src/quic_tx.c:636 #3 0x560b5d981b53 in qc_send_app_pkts src/quic_tx.c:876 #4 0x560b5d987122 in qc_send_app_probing src/quic_tx.c:910 #5 0x560b5d987122 in qc_dgrams_retransmit src/quic_tx.c:1397 #6 0x560b5d8ab250 in quic_conn_app_io_cb src/quic_conn.c:712 #7 0x560b5de41593 in run_tasks_from_lists src/task.c:596 #8 0x560b5de4333c in process_runnable_tasks src/task.c:876 #9 0x560b5dd6f2b0 in run_poll_loop src/haproxy.c:2966 #10 0x560b5dd700fb in run_thread_poll_loop src/haproxy.c:3165 #11 0x7f9ab9188ea6 in start_thread nptl/pthread_create.c:477 #12 0x7f9ab90a8a2e in __clone (/lib/x86_64-linux-gnu/libc.so.6+0xfba2e) AddressSanitizer can not provide additional info. SUMMARY: AddressSanitizer: SEGV include/haproxy/task.h:209 in _task_wakeup Thread T3 created by T0 here: #0 0x7f9ab97ac2a2 in __interceptor_pthread_create ../../../../src/libsaniti zer/asan/asan_interceptors.cpp:214 #1 0x560b5df4f3ef in setup_extra_threads src/thread.c:252 o #2 0x560b5dd730c7 in main src/haproxy.c:3856 #3 0x7f9ab8fd0d09 in __libc_start_main ../csu/libc-start.c:308 i ==21018==ABORTING AddressSanitizer:DEADLYSIGNAL Aborted (core dumped) To fix, simply reset the connection flag QUIC_FL_CONN_RETRANS_NEEDED to cancel the retransmission when qc_kill_conn is called. Note that this new bug arrived with this fix which is correct and flagged as to be backported as far as 2.6. BUG/MINOR: quic: idle timer task requeued in the past Must be backported as far as 2.6. (cherry picked from commit 756b3c5f7b4e2074bf69ac96ffc05c6aa65b1b67) Signed-off-by: Christopher Faulet --- src/quic_conn.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/quic_conn.c b/src/quic_conn.c index c5bec14e8e855..64f90802e41b0 100644 --- a/src/quic_conn.c +++ b/src/quic_conn.c @@ -842,6 +842,7 @@ void qc_kill_conn(struct quic_conn *qc) TRACE_ENTER(QUIC_EV_CONN_KILL, qc); TRACE_PROTO("killing the connection", QUIC_EV_CONN_KILL, qc); qc->flags |= QUIC_FL_CONN_TO_KILL; + qc->flags &= ~QUIC_FL_CONN_RETRANS_NEEDED; task_wakeup(qc->idle_timer_task, TASK_WOKEN_OTHER); qc_notify_err(qc);