CRITICAL Introduced in 5.10
bpf skmsg VerdictReady UAF
CVE-2026-64025
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
KernelScan AI7.0HIGH
01Description
In the Linux kernel, the following vulnerability has been resolved: bpf, skmsg: fix verdict sk_data_ready racing with ktls rx sk_psock_strp_data_ready() already checks tls_sw_has_ctx_rx() and defers to psock->saved_data_ready when a TLS RX context is present, avoiding a conflict with the TLS strparser's ownership of the receive queue (commit e91de6afa81c, "bpf: Fix running sk_skb program types with ktls"). sk_psock_verdict_data_ready() has no equivalent guard. When a socket is inserted into a sockmap (BPF_SK_SKB_VERDICT) before TLS RX is configured, tls_sw_strparser_arm() saves sk_psock_verdict_data_ready as rx_ctx->saved_data_ready. On data arrival: tls_data_ready -> tls_strp_data_ready -> tls_rx_msg_ready -> saved_data_ready() = sk_psock_verdict_data_ready() -> tcp_read_skb() drains sk_receive_queue via __skb_unlink() without calling tcp_eat_skb(), so copied_seq is not advanced. tls_strp_msg_load() then finds tcp_inq() >= full_len (stale), calls tcp_recv_skb() on the now-empty queue, hits WARN_ON_ONCE(!first), and returns with rx_ctx->strp.anchor.frag_list pointing at a psock-owned (potentially freed) skb. tls_decrypt_sg() subsequently walks that frag_list: use-after-free. Apply the same fix as sk_psock_strp_data_ready(): if a TLS RX context is present, call psock->saved_data_ready (sock_def_readable) to wake recv() waiters and return immediately, leaving the receive queue untouched. TLS retains sole ownership of the queue and decrypts the record normally through tls_sw_recvmsg().
02KernelScan AI Analysis
Risk summary
A local user with access to BPF sockmap functionality can trigger a use-after-free in the kernel's TLS receive path by inserting a socket into a sockmap with BPF_SK_SKB_VERDICT before TLS RX is configured. When data arrives, the verdict data_ready callback drains the receive queue without proper coordination with the TLS strparser, leaving a dangling frag_list pointer that tls_decrypt_sg() subsequently dereferences. This can lead to kernel memory corruption, information disclosure, or a system crash.
Vulnerability analysis
The root cause is that sk_psock_verdict_data_ready() lacked the same TLS RX context guard present in sk_psock_strp_data_ready(). When a socket is added to a sockmap (BPF_SK_SKB_VERDICT) before TLS RX is configured, tls_sw_strparser_arm() saves sk_psock_verdict_data_ready as rx_ctx->saved_data_ready. On data arrival, the call chain tls_data_ready -> tls_strp_data_ready -> tls_rx_msg_ready -> saved_data_ready() invokes sk_psock_verdict_data_ready(), which calls tcp_read_skb() and drains sk_receive_queue via __skb_unlink() without advancing copied_seq. The TLS strparser then finds tcp_inq() reporting stale data, calls tcp_recv_skb() on the now-empty queue, and returns with rx_ctx->strp.anchor.frag_list pointing at a psock-owned (potentially already freed) skb. When tls_decrypt_sg() subsequently walks that frag_list, it accesses freed memory. The fix mirrors the existing guard in sk_psock_strp_data_ready(): if a TLS RX context is present, immediately call psock->saved_data_ready (sock_def_readable) to wake waiters and return, leaving the receive queue exclusively owned by the TLS layer. Exploitation requires a local user with CAP_BPF or equivalent access to load BPF programs and manipulate sockmaps, combined with a specific ordering of sockmap insertion before TLS RX setup, making AC:High appropriate.
Lifecycle
03Fix Versions
| Branch | Introduced | Fixed in | Patch commit |
|---|---|---|---|
| 6.18 | 5.10 | 6.18.34 | 1861d369efd6 |
| 6.12 | 5.10 | 6.12.92 | 7c8cf21bc4ef |
| 7.0 | 5.10 | 7.0.11 | 8a52139560f8 |
| 6.6 | 5.10 | 6.6.142 | c9ea01768903 |
| mainline | 5.10 | 7.1 | ddf8029623a1 |