Re: [PATCH] bpf: Fix NULL deref in __list_del_clearprev for flush_node

2 views
Skip to first unread message

bot+b...@kernel.org

unread,
Dec 15, 2025, 10:34:15 PM (13 hours ago) Dec 15
to dongl...@126.com, syzbot+2b3391...@syzkaller.appspotmail.com, and...@kernel.org, a...@kernel.org, b...@vger.kernel.org, dan...@iogearbox.net, da...@davemloft.net, edd...@gmail.com, hao...@google.com, ha...@kernel.org, john.fa...@gmail.com, jo...@kernel.org, kps...@kernel.org, ku...@kernel.org, linux-...@vger.kernel.org, marti...@linux.dev, net...@vger.kernel.org, s...@fomichev.me, so...@kernel.org, syzkall...@googlegroups.com, yongho...@linux.dev, dongl...@126.com, marti...@kernel.org, c...@meta.com, ihor.s...@linux.dev
> diff --git a/kernel/bpf/cpumap.c b/kernel/bpf/cpumap.c
> index 04171fbc39cb..6ab6eae31989 100644
> --- a/kernel/bpf/cpumap.c
> +++ b/kernel/bpf/cpumap.c
> @@ -450,6 +450,7 @@ __cpu_map_entry_alloc(struct bpf_map *map, struct bpf_cpumap_val *value,
>
> for_each_possible_cpu(i) {
> bq = per_cpu_ptr(rcpu->bulkq, i);
> + INIT_LIST_HEAD(&bq->flush_node);
> bq->obj = rcpu;
> }
>

[ ... ]

> diff --git a/kernel/bpf/devmap.c b/kernel/bpf/devmap.c
> index 2625601de76e..7a7347e709cc 100644
> --- a/kernel/bpf/devmap.c
> +++ b/kernel/bpf/devmap.c
> @@ -428,7 +428,8 @@ void __dev_flush(struct list_head *flush_list)
> bq_xmit_all(bq, XDP_XMIT_FLUSH);
> bq->dev_rx = NULL;
> bq->xdp_prog = NULL;
> - __list_del_clearprev(&bq->flush_node);
> + if (bq->flush_node.prev)
> + __list_del_clearprev(&bq->flush_node);
^^^^

The devmap code adds the same defensive check but doesn't initialize
flush_node the way cpumap does. Looking at dev_map_notification(), when
NETDEV_REGISTER occurs, it calls:

alloc_percpu(struct xdp_dev_bulk_queue)

And then only initializes the dev field:

per_cpu_ptr(netdev->xdp_bulkq, cpu)->dev = netdev;

Without INIT_LIST_HEAD(&bq->flush_node), if alloc_percpu() returns
memory with non-zero bytes, bq->flush_node.prev could contain garbage.

The enqueue path in bq_enqueue() uses:

if (!bq->dev_rx)
list_add(&bq->flush_node, flush_list);

So if dev_rx contains non-zero garbage, the node never gets added to the
list. But this flush code checks bq->flush_node.prev which could also be
garbage, causing __list_del_clearprev() to be called with invalid
pointers.

Does devmap need INIT_LIST_HEAD(&bq->flush_node) similar to cpumap? The
commit message states that initialization is part of the fix, but only
cpumap gets it.

[ ... ]


---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md

CI run summary: https://github.com/kernel-patches/bpf/actions/runs/20255377282
Reply all
Reply to author
Forward
0 new messages