]> git.ipfire.org Git - thirdparty/kernel/linux.git/commit
bpf: clear list node owner and unlink before drop
authorKaitao Cheng <chengkaitao@kylinos.cn>
Thu, 21 May 2026 03:23:00 +0000 (11:23 +0800)
committerAlexei Starovoitov <ast@kernel.org>
Thu, 21 May 2026 09:47:45 +0000 (02:47 -0700)
commitcfa6afa4b931aed08288454943e5077f114fd7f3
tree5c05fcc76b2c0ba35c7ea0b043066875635cbf2c
parentcb339ac61d72f7fb7f57bfc0516b7b2b65bc1bad
bpf: clear list node owner and unlink before drop

The issue only becomes exposed once bpf_list_del() is available: callers
can pass an arbitrary bpf_list_head and bpf_list_node pair, including
nodes that are not actually linked to the supplied head, or nodes that
outlive their original head after refcount-based retention.  This was
not practically reachable for callers restricted to pop-style helpers
alone; bpf_list_del() widens the API surface.

A failure mode appears when bpf_list_head_free() runs while a program
still holds an independent refcount on a node (for example via
bpf_refcount_acquire()).  The list head value embedded in map memory can
go away while the node object survives.  If node->owner is left pointing
at the old head address until drop completes, that pointer becomes stale.
If a new bpf_list_head is later allocated at the same address and the
stale node is passed to bpf_list_del(), the owner comparison can succeed
even though the node is not really linked to the new head, and
list_del_init() will follow bogus next/prev pointers with the risk of
memory corruption.

When draining a bpf_list_head, mark each node owner with BPF_PTR_POISON
under the map spinlock while moving it to a private drain list, then
list_del_init() the node and clear owner to NULL before calling
__bpf_obj_drop_impl().  Concurrent readers therefore never observe a
node that appears linked to a head while its list_head is inconsistent,
and surviving refcounted nodes never retain a stale non-NULL owner.

Signed-off-by: Kaitao Cheng <chengkaitao@kylinos.cn>
Link: https://lore.kernel.org/r/20260521032306.97118-3-kaitao.cheng@linux.dev
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
kernel/bpf/helpers.c