From: sashiko-bot@kernel.org
To: "Samuel Wu" <wusamuel@google.com>
Cc: bpf@vger.kernel.org
Subject: Re: [PATCH v4 1/2] PM: wakeup: Add kfuncs to traverse over wakeup_sources
Date: Tue, 12 May 2026 23:36:59 +0000 [thread overview]
Message-ID: <20260512233659.CFEEFC2BCF6@smtp.kernel.org> (raw)
In-Reply-To: <20260511174559.659782-2-wusamuel@google.com>
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] The kfunc `bpf_wakeup_sources_get_head()` returns `void *` instead of `struct list_head *`, which the BPF verifier downgrades to an unknown scalar, destroying BTF type tracking.
- [High] The verifier cannot enforce that the SRCU lock is actually held during list traversal, allowing trivial use-after-free vulnerabilities and violating BPF architectural patterns.
- [Medium] Wrapping the integer SRCU index in a fake `struct bpf_ws_lock *` pointer circumvents verifier safeguards and introduces invalid trusted pointers.
--
commit 6dcbdc1d5aa4a12914c7281f95390e19498129d0
Author: Samuel Wu <wusamuel@google.com>
PM: wakeup: Add kfuncs to traverse over wakeup_sources
This patch introduces BPF kfuncs to allow in-kernel traversal of the
wakeup_sources list. It adds functions to get the list head and manage
the SRCU lock, using an opaque pointer to hold the SRCU index for the
verifier.
> diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c
> index b8e48a023bf0c..80b497de2deb0 100644
> --- a/drivers/base/power/wakeup.c
> +++ b/drivers/base/power/wakeup.c
[ ... ]
> +/**
> + * bpf_wakeup_sources_read_lock - Acquire the SRCU lock for wakeup sources
> + *
> + * The underlying SRCU lock returns an integer index. However, the BPF verifier
> + * requires a pointer (PTR_TO_BTF_ID) to strictly track the state of acquired
> + * resources using KF_ACQUIRE and KF_RELEASE semantics. We use an opaque
> + * structure pointer (struct bpf_ws_lock *) to satisfy the verifier while
> + * safely encoding the integer index within the pointer address itself.
> + *
> + * Return: An opaque pointer encoding the SRCU lock index + 1 (to avoid NULL).
> + */
> +__bpf_kfunc struct bpf_ws_lock *bpf_wakeup_sources_read_lock(void)
> +{
> + return (struct bpf_ws_lock *)(long)(wakeup_sources_read_lock() + 1);
> +}
The verifier treats the returned struct bpf_ws_lock * as a trusted
PTR_TO_BTF_ID. By casting the integer index returned by srcu_read_lock()
into a pointer, we end up fabricating invalid kernel pointers pointing to
near-zero addresses like 0x1 or 0x2.
Does this circumvent verifier safeguards by introducing invalid trusted
pointers?
[ ... ]
> +/**
> + * bpf_wakeup_sources_read_unlock - Release the SRCU lock for wakeup sources
> + * @lock: The opaque pointer returned by bpf_wakeup_sources_read_lock()
> + *
> + * The BPF verifier guarantees that @lock is a valid, unreleased pointer from
> + * the acquire function. We decode the pointer back into the integer SRCU index
> + * by subtracting 1 and release the lock.
> + */
> +__bpf_kfunc void bpf_wakeup_sources_read_unlock(struct bpf_ws_lock *lock)
> +{
> + wakeup_sources_read_unlock((int)(long)lock - 1);
> +}
The patch uses KF_ACQUIRE and KF_RELEASE to ensure the lock is eventually
unlocked. However, does the BPF verifier have a mechanism to tie this
custom lock state to the list pointer returned by
bpf_wakeup_sources_get_head()?
It seems a BPF program could fetch the list head and traverse it without
ever acquiring the lock, or continue accessing elements after releasing
the lock, resulting in a use-after-free.
Would it be safer to implement a dedicated BPF iterator
(bpf_iter_wakeup_source) that internally manages the SRCU lock and safely
yields elements, rather than exposing the raw lock and list head?
> +/**
> + * bpf_wakeup_sources_get_head - Get the head of the wakeup sources list
> + *
> + * Return: The head of the wakeup sources list.
> + */
> +__bpf_kfunc void *bpf_wakeup_sources_get_head(void)
> +{
> + return &wakeup_sources;
> +}
Since this kfunc returns void * instead of struct list_head *, the BPF
verifier evaluates it as returning an unknown scalar.
Because the return value becomes a scalar, BPF programs cannot natively
or safely dereference the list head. They would be forced to cast the
scalar back into a pointer using bpf_rdonly_cast(), which the verifier
marks as PTR_UNTRUSTED.
Since untrusted pointers cause field dereferences to be rewritten into
slow PROBE_MEM operations, does this defeat the goal of high-performance
in-kernel traversal?
Could the return type be changed to struct list_head * to be natively
tracked as a PTR_TO_BTF_ID?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260511174559.659782-1-wusamuel@google.com?part=1
next prev parent reply other threads:[~2026-05-12 23:37 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-11 17:45 [PATCH v4 0/2] Support BPF traversal of wakeup sources Samuel Wu
2026-05-11 17:45 ` [PATCH v4 1/2] PM: wakeup: Add kfuncs to traverse over wakeup_sources Samuel Wu
2026-05-11 18:27 ` bot+bpf-ci
2026-05-11 20:06 ` Samuel Wu
2026-05-12 23:36 ` sashiko-bot [this message]
2026-05-11 17:45 ` [PATCH v4 2/2] selftests/bpf: Add tests for wakeup_sources kfuncs Samuel Wu
2026-05-12 23:58 ` sashiko-bot
2026-05-11 20:44 ` [PATCH v4 0/2] Support BPF traversal of wakeup sources Kumar Kartikeya Dwivedi
2026-05-13 0:51 ` Alexei Starovoitov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260512233659.CFEEFC2BCF6@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
--cc=wusamuel@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox