[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <0823b48aff04b144bc67d0e4d3c633ad80ed3feb94f546a911de01592aaac049@mail.kernel.org>
Date: Thu, 8 Jan 2026 23:21:50 +0000 (UTC)
From: bot+bpf-ci@...nel.org
To: wusamuel@...gle.com,ast@...nel.org,daniel@...earbox.net,andrii@...nel.org,martin.lau@...ux.dev,eddyz87@...il.com,song@...nel.org,yonghong.song@...ux.dev,john.fastabend@...il.com,kpsingh@...nel.org,sdf@...ichev.me,haoluo@...gle.com,jolsa@...nel.org,shuah@...nel.org
Cc: wusamuel@...gle.com,kernel-team@...roid.com,linux-kernel@...r.kernel.org,bpf@...r.kernel.org,linux-kselftest@...r.kernel.org,ast@...nel.org,andrii@...nel.org,daniel@...earbox.net,martin.lau@...nel.org,eddyz87@...il.com,yonghong.song@...ux.dev,clm@...a.com,ihor.solodrai@...ux.dev
Subject: Re: [PATCH bpf-next v2 2/4] bpf: Open coded BPF for wakeup_sources
> diff --git a/kernel/bpf/wakeup_source_iter.c b/kernel/bpf/wakeup_source_iter.c
> index ab83d212a1f9..149baecfe436 100644
> --- a/kernel/bpf/wakeup_source_iter.c
> +++ b/kernel/bpf/wakeup_source_iter.c
[ ... ]
> +__bpf_kfunc int bpf_iter_wakeup_source_new(struct bpf_iter_wakeup_source *it)
> +{
> + it->srcuidx = wakeup_sources_read_lock();
> + it->ws = wakeup_sources_walk_start();
> +
> + return 0;
> +}
> +
> +__bpf_kfunc struct wakeup_source *bpf_iter_wakeup_source_next(struct bpf_iter_wakeup_source *it)
> +{
> + struct wakeup_source *prev = it->ws;
> +
> + if (!prev)
> + return NULL;
> +
> + it->ws = wakeup_sources_walk_next(it->ws);
> +
> + return prev;
> +}
When the wakeup_sources list is empty, wakeup_sources_walk_start() returns
a bogus pointer via list_entry_rcu()/container_of() on the list head itself,
rather than NULL. The check "if (!prev)" at line 112 will not catch this
bogus pointer since it is non-NULL.
Does this return a bogus pointer to the BPF program when the wakeup_sources
list is empty? If so, the BPF program could then access invalid memory when
it tries to read fields of the returned wakeup_source.
For reference, wakeup_sources_walk_start() in drivers/base/power/wakeup.c:
struct wakeup_source *wakeup_sources_walk_start(void)
{
struct list_head *ws_head = &wakeup_sources;
return list_entry_rcu(ws_head->next, struct wakeup_source, entry);
}
When wakeup_sources is empty, ws_head->next == ws_head, so this returns
container_of(ws_head, struct wakeup_source, entry) which points to memory
before the wakeup_sources variable rather than a valid wakeup_source struct.
Other BPF open-coded iterators like bpf_iter_dmabuf handle this differently
by initializing to NULL and getting the first element lazily in _next().
Would a similar approach work here?
---
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/20835022582
Powered by blists - more mailing lists