From: Xingwang Xiang <v3rdant.xiang@gmail.com> mainline inclusion from mainline-v7.1-rc5 commit ddf8029623a1 ("bpf, skmsg: fix verdict sk_data_ready racing with ktls rx") category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/16350 CVE: CVE-2026-64025 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i... -------------------------------- 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(). Fixes: ef5659280eb1 ("bpf, sockmap: Allow skipping sk_skb parser program") Signed-off-by: Xingwang Xiang <v3rdant.xiang@gmail.com> Link: https://patch.msgid.link/20260517145630.20521-2-v3rdant.xiang@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> Conflicts: net/core/skmsg.c [commit ddf8029623a is not backport, which lead to conflicts Adaptation notes: - The upstream mainline function uses rcu_read_lock(), sk_psock(), READ_ONCE(sk->sk_socket) and ops->read_skb. The OLK-5.10 version of sk_psock_verdict_data_ready() uses the legacy sock->ops->read_sock path without RCU protection. - Transplanted the TLS RX guard by taking rcu_read_lock(), obtaining struct sk_psock *psock, and calling psock->parser.saved_data_ready(sk) (in 5.10 saved_data_ready lives inside struct sk_psock_parser) before returning, leaving the receive queue untouched for ktls. - This preserves the same logic as sk_psock_strp_data_ready() which already performs tls_sw_has_ctx_rx() detection in this tree.] Signed-off-by: Dong Chenchen <dongchenchen2@huawei.com> --- net/core/skmsg.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/net/core/skmsg.c b/net/core/skmsg.c index 5150fc93dd9b..b979a4cba4d2 100644 --- a/net/core/skmsg.c +++ b/net/core/skmsg.c @@ -1056,11 +1056,21 @@ static int sk_psock_verdict_recv(read_descriptor_t *desc, struct sk_buff *skb, static void sk_psock_verdict_data_ready(struct sock *sk) { struct socket *sock = sk->sk_socket; + struct sk_psock *psock; read_descriptor_t desc; if (unlikely(!sock || !sock->ops || !sock->ops->read_sock)) return; + rcu_read_lock(); + psock = sk_psock(sk); + if (psock && tls_sw_has_ctx_rx(sk)) { + psock->parser.saved_data_ready(sk); + rcu_read_unlock(); + return; + } + rcu_read_unlock(); + desc.arg.data = sk; desc.error = 0; desc.count = 1; -- 2.43.0