摘要:
In the Linux kernel, the following vulnerability has been resolved:
bpf, sockmap: Check for any of tcp_bpf_prots when cloning a listener
A listening socket linked to a sockmap has its sk_prot overridden. It
points to one of the struct proto variants in tcp_bpf_prots. The variant
depends on the socket's family and which sockmap programs are attached.
A child socket cloned from a TCP listener initially inherits their sk_prot.
But before cloning is finished, we restore the child's proto to the
listener's original non-tcp_bpf_prots one. This happens in
tcp_create_openreq_child -> tcp_bpf_clone.
Today, in tcp_bpf_clone we detect if the child's proto should be restored
by checking only for the TCP_BPF_BASE proto variant. This is not
correct. The sk_prot of listening socket linked to a sockmap can point to
to any variant in tcp_bpf_prots.
If the listeners sk_prot happens to be not the TCP_BPF_BASE variant, then
the child socket unintentionally is left if the inherited sk_prot by
tcp_bpf_clone.
This leads to issues like infinite recursion on close [1], because the
child state is otherwise not set up for use with tcp_bpf_prot operations.
Adjust the check in tcp_bpf_clone to detect all of tcp_bpf_prots variants.
Note that it wouldn't be sufficient to check the socket state when
overriding the sk_prot in tcp_bpf_update_proto in order to always use the
TCP_BPF_BASE variant for listening sockets. Since commit
b8b8315e39ff ("bpf, sockmap: Remove unhash handler for BPF sockmap usage")
it is possible for a socket to transition to TCP_LISTEN state while already
linked to a sockmap, e.g. connect() -> insert into map ->
connect(AF_UNSPEC) -> listen().
[1]: https://lore.kernel.org/all/00000000000073b14905ef2e7401@google.com/
安全等级: Low
公告ID: KylinSec-SA-2025-2352
发布日期: 2025年4月20日
关联CVE: CVE-2023-52986
在 Linux 内核中,以下漏洞已被修复:
bpf, sockmap: 克隆监听器时检查所有 tcp_bpf_prots 变体
链接到 sockmap 的监听套接字会覆盖其 sk_prot。它指向 tcp_bpf_prots 中的某个 struct proto 变体。具体变体取决于套接字的协议族以及附加的 sockmap 程序。
从 TCP 监听器克隆的子套接字最初会继承其 sk_prot。但在克隆完成前,我们会将子套接字的 proto 恢复为监听器原始的非 tcp_bpf_prots 版本。这一过程发生在 tcp_create_openreq_child -> tcp_bpf_clone 中。
当前在 tcp_bpf_clone 中,我们仅通过检查 TCP_BPF_BASE proto 变体来判断是否应该恢复子套接字的 proto。这是不正确的。链接到 sockmap 的监听套接字的 sk_prot 可能指向 tcp_bpf_prots 中的任何变体。
如果监听器的 sk_prot 恰好不是 TCP_BPF_BASE 变体,那么子套接字将在 tcp_bpf_clone 中意外保留继承的 sk_prot。
这会导致诸如关闭时无限递归等问题 [1],因为子套接字状态并未设置为用于 tcp_bpf_prot 操作。
调整 tcp_bpf_clone 中的检查逻辑以检测所有 tcp_bpf_prots 变体。
需要注意的是,为了始终对监听套接字使用 TCP_BPF_BASE 变体,仅通过在 tcp_bpf_update_proto 中覆盖 sk_prot 时检查套接字状态是不够的。自 commit b8b8315e39ff ("bpf, sockmap: Remove unhash handler for BPF sockmap usage") 起,套接字有可能在已经链接到 sockmap 的情况下转换到 TCP_LISTEN 状态,例如:connect() -> 插入到 map -> connect(AF_UNSPEC) -> listen()。
[1]: https://lore.kernel.org/all/00000000000073b14905ef2e7401@google.com/
cve名称 | 产品 | 组件 | 是否受影响 |
---|---|---|---|
CVE-2023-52986 | KY3.4-5A | kernel | Unaffected |
CVE-2023-52986 | V6 | kernel | Unaffected |