From: Puranjay Mohan <puranjay@kernel.org>
To: sashiko-reviews@lists.linux.dev, chenyuan_fl@163.com
Cc: bpf@vger.kernel.org, Puranjay Mohan <puranjay12@gmail.com>
Subject: Re: [PATCH bpf-next v2 3/3] bpf, arena: check range_tree_set return in arena_free_pages and arena_free_worker
Date: Mon, 10 Aug 2026 14:19:58 +0100 [thread overview]
Message-ID: <m2ecg66rk1.fsf@kernel.org> (raw)
In-Reply-To: <20260810100047.946191F00A3A@smtp.kernel.org>
sashiko-bot@kernel.org writes:
> Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
>
> Pre-existing issues:
> - [High] A race condition between dropping the arena spinlock and flushing the TLB allows concurrent reallocation and stale TLB access, leading to an information leak.
> --
>
> --- Patch [3]: [PATCH bpf-next v2 3/3] bpf, arena: check range_tree_set return in arena_free_pages and arena_free_worker ---
> commit d52cc998404e8cd2b8a37ee307bab5c587ce8336
> Author: Yuan Chen <chenyuan@kylinos.cn>
>
> bpf, arena: check range_tree_set return in arena_free_pages and arena_free_worker
>
> arena_free_pages() and arena_free_worker() now handle range_tree_set()
> errors. arena_free_pages() aborts the free on error, and
> arena_free_worker() moves range_tree_set() before PTE clearing so that a
> failed tree update leaves the PTEs intact instead of freeing pages that
> the arena free tree does not track.
>
>> diff --git a/kernel/bpf/arena.c b/kernel/bpf/arena.c
>> index 7b6847200b431..4597d9becb97a 100644
>> --- a/kernel/bpf/arena.c
>> +++ b/kernel/bpf/arena.c
>> @@ -881,7 +881,12 @@ static void arena_free_pages(struct bpf_arena *arena, long uaddr, long page_cnt,
>> if (ret)
>> goto defer;
>>
>> - range_tree_set(&arena->rt, pgoff, page_cnt);
>> + ret = range_tree_set(&arena->rt, pgoff, page_cnt);
>> + if (ret) {
>> + raw_res_spin_unlock_irqrestore(&arena->spinlock, flags);
>> + bpf_map_memcg_exit(old_memcg, new_memcg);
>> + return;
>> + }
>
> [Severity: High]
> This is a pre-existing issue, but does marking the range as free here,
> before dropping the spinlock and flushing the TLB, create a race condition?
>
> If CPU 1 calls arena_free_pages(), marks the pages as free via
> range_tree_set(), clears the PTEs, and drops the spinlock:
>
> ret = range_tree_set(&arena->rt, pgoff, page_cnt);
> ...
> raw_res_spin_unlock_irqrestore(&arena->spinlock, flags);
>
> Before CPU 1 executes flush_tlb_kernel_range(), could CPU 2 allocate the
> same virtual address via bpf_arena_alloc_pages() and populate new PTEs?
>
> If CPU 2 (or another CPU) previously accessed this virtual address, its
> TLB might still point to the old physical page. Writes to this address
> would then incorrectly modify the old physical page.
>
> CPU 1 would then flush the TLB and free the old physical page to the buddy
> allocator, potentially leaking sensitive data to other processes.
>
> [ ... ]
>
>> @@ -1004,11 +1009,18 @@ static void arena_free_worker(struct work_struct *work)
>> kaddr = arena_vm_start + s->uaddr;
>> pgoff = compute_pgoff(arena, s->uaddr);
>>
>> + /*
>> + * Mark the range as free before clearing PTEs so that
>> + * if the range tree update fails we leave the PTEs
>> + * intact, avoiding an unrecoverable state where pages
>> + * are freed but the arena free tree does not track them.
>> + */
>> + if (range_tree_set(&arena->rt, pgoff, page_cnt))
>> + continue;
>
> [Severity: High]
> This isn't a bug introduced by this patch, but does the same race
> condition exist here in the asynchronous worker?
>
> The worker marks the range as free via range_tree_set() and drops the
> spinlock:
>
> if (range_tree_set(&arena->rt, pgoff, page_cnt))
> continue;
> ...
> raw_res_spin_unlock_irqrestore(&arena->spinlock, flags);
>
> Before iterating the list again to call flush_tlb_kernel_range(), this
> seems to expose the old physical pages to the same concurrent reallocation
> race window as arena_free_pages().
>
Both these issues are real and I am working on a fix for these. I
already saw them while fuzzing the BPF JITs through litmus tests.
Will post the patch soon.
Thanks,
Puranjay
next prev parent reply other threads:[~2026-08-10 13:20 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-10 9:46 [PATCH bpf-next v2 0/3] bpf, arena: fix range_tree consistency on allocation failure chenyuan_fl
2026-08-10 9:46 ` [PATCH bpf-next v2 1/3] bpf, arena: fix range_tree_clear inconsistency on kmalloc_nolock failure chenyuan_fl
2026-08-10 10:00 ` sashiko-bot
2026-08-10 10:45 ` bot+bpf-ci
2026-08-10 9:46 ` [PATCH bpf-next v2 2/3] bpf, arena: fix range_tree_set " chenyuan_fl
2026-08-10 10:59 ` bot+bpf-ci
2026-08-10 9:46 ` [PATCH bpf-next v2 3/3] bpf, arena: check range_tree_set return in arena_free_pages and arena_free_worker chenyuan_fl
2026-08-10 10:00 ` sashiko-bot
2026-08-10 13:19 ` Puranjay Mohan [this message]
2026-08-10 10:59 ` bot+bpf-ci
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=m2ecg66rk1.fsf@kernel.org \
--to=puranjay@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=chenyuan_fl@163.com \
--cc=puranjay12@gmail.com \
--cc=sashiko-reviews@lists.linux.dev \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.