bot+b...@kernel.org
unread,Dec 15, 2025, 10:34:15 PM (13 hours ago) Dec 15Sign in to reply to author
Sign in to forward
You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
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