Re: [PATCH] bpf: arena: Flush stale TLB entries before reusing ranges
From: Andrea Righi
Date: Sun Sep 20 2026 - 02:07:49 EST
Hi Alexei,
On Sat, Sep 19, 2026 at 11:21:43PM +0000, Alexei Starovoitov wrote:
> On Sun, Sep 20, 2026 at 12:46 AM Andrea Righi <arighi@xxxxxxxxxx> wrote:
> > @@ -911,11 +910,17 @@ static void arena_free_pages(struct bpf_arena *arena, long uaddr, long page_cnt,
> > zap_pages(arena, full_uaddr, 1);
> > __free_page(page);
> > }
> > +
> > + ret = raw_res_spin_lock_irqsave(&arena->spinlock, flags);
> > + if (ret)
> > + goto defer_publish;
> > + range_tree_set(&arena->rt, pgoff, page_cnt);
> > + raw_res_spin_unlock_irqrestore(&arena->spinlock, flags);
>
> Now the ptes are cleared in one locked section and the range is set in
> another, and arena_vm_fault() can get in between. It doesn't look at
> the range tree to decide. It does vmalloc_to_page(), sees no page,
> range_tree_clear() of an already clear range returns 0, so it allocates
> a page and installs it into the kernel pte. Then the code above marks
> that range free. The next bpf_arena_alloc_pages() that picks it hits
> WARN_ON_ONCE(pte_page(old) != d->arena->scratch_page)
> in apply_range_set_cb(), returns NULL, puts t
> he range back into the
> tree, and the next call does the same. All it takes is user space
> touching the page while the prog frees it.
You're right, I missed that range_tree_clear() succeeds even when the range is
already clear, so arena_vm_fault() populates the range during the
teardown-to-publish window, leaving the range marked free with a valid PTE
installed.
>
> iirc Emil has patches that address this issue differently.
Thanks for catching this! I'll sync with Emil.
-Andrea