CVE-2024-50154

Severity CVSS v4.0:
Pending analysis
Type:
CWE-416 Use After Free
Publication date:
07/11/2024
Last modified:
03/11/2025

Description

In the Linux kernel, the following vulnerability has been resolved:<br /> <br /> tcp/dccp: Don&amp;#39;t use timer_pending() in reqsk_queue_unlink().<br /> <br /> Martin KaFai Lau reported use-after-free [0] in reqsk_timer_handler().<br /> <br /> """<br /> We are seeing a use-after-free from a bpf prog attached to<br /> trace_tcp_retransmit_synack. The program passes the req-&gt;sk to the<br /> bpf_sk_storage_get_tracing kernel helper which does check for null<br /> before using it.<br /> """<br /> <br /> The commit 83fccfc3940c ("inet: fix potential deadlock in<br /> reqsk_queue_unlink()") added timer_pending() in reqsk_queue_unlink() not<br /> to call del_timer_sync() from reqsk_timer_handler(), but it introduced a<br /> small race window.<br /> <br /> Before the timer is called, expire_timers() calls detach_timer(timer, true)<br /> to clear timer-&gt;entry.pprev and marks it as not pending.<br /> <br /> If reqsk_queue_unlink() checks timer_pending() just after expire_timers()<br /> calls detach_timer(), TCP will miss del_timer_sync(); the reqsk timer will<br /> continue running and send multiple SYN+ACKs until it expires.<br /> <br /> The reported UAF could happen if req-&gt;sk is close()d earlier than the timer<br /> expiration, which is 63s by default.<br /> <br /> The scenario would be<br /> <br /> 1. inet_csk_complete_hashdance() calls inet_csk_reqsk_queue_drop(),<br /> but del_timer_sync() is missed<br /> <br /> 2. reqsk timer is executed and scheduled again<br /> <br /> 3. req-&gt;sk is accept()ed and reqsk_put() decrements rsk_refcnt, but<br /> reqsk timer still has another one, and inet_csk_accept() does not<br /> clear req-&gt;sk for non-TFO sockets<br /> <br /> 4. sk is close()d<br /> <br /> 5. reqsk timer is executed again, and BPF touches req-&gt;sk<br /> <br /> Let&amp;#39;s not use timer_pending() by passing the caller context to<br /> __inet_csk_reqsk_queue_drop().<br /> <br /> Note that reqsk timer is pinned, so the issue does not happen in most<br /> use cases. [1]<br /> <br /> [0]<br /> BUG: KFENCE: use-after-free read in bpf_sk_storage_get_tracing+0x2e/0x1b0<br /> <br /> Use-after-free read at 0x00000000a891fb3a (in kfence-#1):<br /> bpf_sk_storage_get_tracing+0x2e/0x1b0<br /> bpf_prog_5ea3e95db6da0438_tcp_retransmit_synack+0x1d20/0x1dda<br /> bpf_trace_run2+0x4c/0xc0<br /> tcp_rtx_synack+0xf9/0x100<br /> reqsk_timer_handler+0xda/0x3d0<br /> run_timer_softirq+0x292/0x8a0<br /> irq_exit_rcu+0xf5/0x320<br /> sysvec_apic_timer_interrupt+0x6d/0x80<br /> asm_sysvec_apic_timer_interrupt+0x16/0x20<br /> intel_idle_irq+0x5a/0xa0<br /> cpuidle_enter_state+0x94/0x273<br /> cpu_startup_entry+0x15e/0x260<br /> start_secondary+0x8a/0x90<br /> secondary_startup_64_no_verify+0xfa/0xfb<br /> <br /> kfence-#1: 0x00000000a72cc7b6-0x00000000d97616d9, size=2376, cache=TCPv6<br /> <br /> allocated by task 0 on cpu 9 at 260507.901592s:<br /> sk_prot_alloc+0x35/0x140<br /> sk_clone_lock+0x1f/0x3f0<br /> inet_csk_clone_lock+0x15/0x160<br /> tcp_create_openreq_child+0x1f/0x410<br /> tcp_v6_syn_recv_sock+0x1da/0x700<br /> tcp_check_req+0x1fb/0x510<br /> tcp_v6_rcv+0x98b/0x1420<br /> ipv6_list_rcv+0x2258/0x26e0<br /> napi_complete_done+0x5b1/0x2990<br /> mlx5e_napi_poll+0x2ae/0x8d0<br /> net_rx_action+0x13e/0x590<br /> irq_exit_rcu+0xf5/0x320<br /> common_interrupt+0x80/0x90<br /> asm_common_interrupt+0x22/0x40<br /> cpuidle_enter_state+0xfb/0x273<br /> cpu_startup_entry+0x15e/0x260<br /> start_secondary+0x8a/0x90<br /> secondary_startup_64_no_verify+0xfa/0xfb<br /> <br /> freed by task 0 on cpu 9 at 260507.927527s:<br /> rcu_core_si+0x4ff/0xf10<br /> irq_exit_rcu+0xf5/0x320<br /> sysvec_apic_timer_interrupt+0x6d/0x80<br /> asm_sysvec_apic_timer_interrupt+0x16/0x20<br /> cpuidle_enter_state+0xfb/0x273<br /> cpu_startup_entry+0x15e/0x260<br /> start_secondary+0x8a/0x90<br /> secondary_startup_64_no_verify+0xfa/0xfb

Vulnerable products and versions

CPE From Up to
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 4.1.11 (including) 4.2 (excluding)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 4.2 (including) 5.15.170 (excluding)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 5.16 (including) 6.1.115 (excluding)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 6.2 (including) 6.6.59 (excluding)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 6.7 (including) 6.11.6 (excluding)
cpe:2.3:o:linux:linux_kernel:6.12:rc1:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:6.12:rc2:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:6.12:rc3:*:*:*:*:*:*