* [PATCH bpf] bpf: Skip unsettled links in link iterator
@ 2026-09-14 17:02 Weiming Shi
2026-09-14 17:16 ` sashiko-bot
2026-09-17 22:10 ` patchwork-bot+netdevbpf
0 siblings, 2 replies; 3+ messages in thread
From: Weiming Shi @ 2026-09-14 17:02 UTC (permalink / raw)
To: Alexei Starovoitov, Daniel Borkmann, John Fastabend,
Andrii Nakryiko, Eduard Zingerman, Kumar Kartikeya Dwivedi,
Martin KaFai Lau, Song Liu, Yonghong Song, Jiri Olsa,
Emil Tsalapatis, Ihor Solodrai
Cc: bpf, linux-kernel, Dmitrii Dolgov, Xiang Mei, Weiming Shi
bpf_link_prime() inserts a link into link_idr before anon_inode_getfile()
succeeds and before bpf_link_settle() publishes the ID in link->id.
bpf_link_by_id() treats such an ID-zero link as unsettled, but the link
iterator takes a reference without this check.
If anon_inode_getfile() then fails, the creator removes the ID and frees
its still-private link directly. The iterator is left with a dangling
reference and its next bpf_link_put() accesses freed memory.
Treat ID-zero entries as transient in bpf_link_get_curr_or_next(), just as
bpf_link_by_id() does.
BUG: KASAN: slab-use-after-free in bpf_link_put
Write of size 8 by task exp/384
Call Trace:
bpf_link_put kernel/bpf/syscall.c:3372
bpf_link_seq_next kernel/bpf/link_iter.c:33
bpf_seq_read kernel/bpf/bpf_iter.c:158
vfs_read fs/read_write.c:572
ksys_read fs/read_write.c:716
do_syscall_64 arch/x86/entry/syscall_64.c:84
entry_SYSCALL_64_after_hwframe arch/x86/entry/entry_64.S:121
Kernel panic - not syncing: KASAN: panic_on_warn set ...
Fixes: 9f8836127308 ("bpf: Add bpf_link iterator")
Reported-by: Xiang Mei <xmei5@asu.edu>
Assisted-by: LLM
Signed-off-by: Weiming Shi <bestswngs@gmail.com>
---
kernel/bpf/syscall.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index a8c9b2865c5df..2870ff3167d42 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -6044,7 +6044,10 @@ struct bpf_link *bpf_link_get_curr_or_next(u32 *id)
again:
link = idr_get_next(&link_idr, id);
if (link) {
- link = bpf_link_inc_not_zero(link);
+ if (link->id)
+ link = bpf_link_inc_not_zero(link);
+ else
+ link = ERR_PTR(-EAGAIN);
if (IS_ERR(link)) {
(*id)++;
goto again;
--
2.55.0
^ permalink raw reply related [flat|nested] 3+ messages in thread* Re: [PATCH bpf] bpf: Skip unsettled links in link iterator
2026-09-14 17:02 [PATCH bpf] bpf: Skip unsettled links in link iterator Weiming Shi
@ 2026-09-14 17:16 ` sashiko-bot
2026-09-17 22:10 ` patchwork-bot+netdevbpf
1 sibling, 0 replies; 3+ messages in thread
From: sashiko-bot @ 2026-09-14 17:16 UTC (permalink / raw)
To: Weiming Shi; +Cc: bpf
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] Preexisting race condition between btf_put() and btf_idr iteration causes refcount saturation and Use-After-Free.
--
commit c9cafeb12312032e3482a8253aec4ec8da20e91f
Author: Weiming Shi <bestswngs@gmail.com>
bpf: Skip unsettled links in link iterator
This commit fixes a use-after-free in the BPF link iterator by ensuring
unsettled links (with ID zero) are skipped during IDR traversal. It prevents
taking references on transient links that might be freed concurrently.
> diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
> index 853b47f813842..244a939b9d2da 100644
> --- a/kernel/bpf/syscall.c
> +++ b/kernel/bpf/syscall.c
> @@ -6042,7 +6042,10 @@ struct bpf_link *bpf_link_get_curr_or_next(u32 *id)
> again:
> link = idr_get_next(&link_idr, id);
> if (link) {
> - link = bpf_link_inc_not_zero(link);
> + if (link->id)
> + link = bpf_link_inc_not_zero(link);
> + else
> + link = ERR_PTR(-EAGAIN);
[Severity: High]
This isn't a bug introduced by this patch, but while looking at this fix for
bpf_link IDR iteration, is there a similar race condition in the BTF IDR
iteration?
In kernel/bpf/btf.c, btf_put() decrements the refcount outside the IDR lock:
kernel/bpf/btf.c:btf_put() {
if (btf && refcount_dec_and_test(&btf->refcnt)) {
...
/* btf_free_id(btf) is called later, acquiring the lock */
Concurrently, iterators like bpf_find_btf_id() or bpf_core_add_cands()
iterate over btf_idr holding btf_idr_lock and unconditionally increment
the refcount via btf_get() (which maps to refcount_inc()).
Could this lead to btf_get() incrementing a 0-refcount object before it is
removed from the IDR?
If the refcount is incremented from 0, it saturates the refcount and triggers
a kernel warning.
Furthermore, after the iterator drops btf_idr_lock to do a slow linear
search without holding rcu_read_lock(), btf_put() can proceed to remove
the ID and schedule the RCU callback to free the BTF memory.
Does this expose the iterator to a use-after-free when accessing the BTF
object later?
Would it be safer to use refcount_inc_not_zero() during BTF IDR traversal,
similar to how bpf_link_inc_not_zero() is used here?
> if (IS_ERR(link)) {
> (*id)++;
> goto again;
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260914170206.170723-2-bestswngs@gmail.com?part=1
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [PATCH bpf] bpf: Skip unsettled links in link iterator
2026-09-14 17:02 [PATCH bpf] bpf: Skip unsettled links in link iterator Weiming Shi
2026-09-14 17:16 ` sashiko-bot
@ 2026-09-17 22:10 ` patchwork-bot+netdevbpf
1 sibling, 0 replies; 3+ messages in thread
From: patchwork-bot+netdevbpf @ 2026-09-17 22:10 UTC (permalink / raw)
To: Weiming Shi
Cc: ast, daniel, john.fastabend, andrii, eddyz87, memxor, martin.lau,
song, yonghong.song, jolsa, emil, ihor.solodrai, bpf,
linux-kernel, 9erthalion6, xmei5
Hello:
This patch was applied to bpf/bpf.git (master)
by Andrii Nakryiko <andrii@kernel.org>:
On Tue, 15 Sep 2026 01:02:07 +0800 you wrote:
> bpf_link_prime() inserts a link into link_idr before anon_inode_getfile()
> succeeds and before bpf_link_settle() publishes the ID in link->id.
> bpf_link_by_id() treats such an ID-zero link as unsettled, but the link
> iterator takes a reference without this check.
>
> If anon_inode_getfile() then fails, the creator removes the ID and frees
> its still-private link directly. The iterator is left with a dangling
> reference and its next bpf_link_put() accesses freed memory.
>
> [...]
Here is the summary with links:
- [bpf] bpf: Skip unsettled links in link iterator
https://git.kernel.org/bpf/bpf/c/50e80e2bb5e2
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-09-17 22:11 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-14 17:02 [PATCH bpf] bpf: Skip unsettled links in link iterator Weiming Shi
2026-09-14 17:16 ` sashiko-bot
2026-09-17 22:10 ` patchwork-bot+netdevbpf
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox