On Tue, May 26, 2026 at 09:46:49PM +0000, [email protected] wrote:
> > commit 68883203f0583fb1a8d79536f5c8945542974abd
> > Author: Jiri Olsa <[email protected]>
> > Date:   Tue May 26 22:58:31 2026 +0200
> >
> >     uprobes/x86: Unmap trampoline vma object in case it's unused
> >
> >     In case the optimization fails, we leak new-ly created trampoline
> >     vma mapping (in case we just created it), let's unmap it.
> >
> >     Fixes: ba2bfc97b462 ("uprobes/x86: Add support to optimize uprobes")
> >     Signed-off-by: Jiri Olsa <[email protected]>
> 
> Should this Fixes: tag point to a9fe6f54968c instead? The vma leak bug
> was actually introduced by commit a9fe6f54968c ("uprobes/x86: Remove
> struct uprobe_trampoline object"), not ba2bfc97b462. Commit a9fe6f54968c
> removed the destroy_uprobe_trampoline() cleanup call, and its commit
> message explicitly states: "The new vma leak is fixed in following
> change."

there's no a9fe6f54968c hash yet

> 
> Suggested: Fixes: a9fe6f54968c ("uprobes/x86: Remove struct
> uprobe_trampoline object")
> 
> > diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
> > index c8af41ed681a..af5af7d67999 100644
> > --- a/arch/x86/kernel/uprobes.c
> > +++ b/arch/x86/kernel/uprobes.c
> > @@ -677,11 +677,14 @@ static unsigned long find_nearest_trampoline(unsigned 
> > long vaddr)
> >     return high_tramp;
> >  }
> >
> > -static struct vm_area_struct *get_uprobe_trampoline(struct mm_struct *mm, 
> > unsigned long vaddr)
> > +static struct vm_area_struct *get_uprobe_trampoline(struct mm_struct *mm, 
> > unsigned long vaddr,
> > +                                               bool *new_mapping)
> >  {
> >     VMA_ITERATOR(vmi, mm, 0);
> >     struct vm_area_struct *vma;
> >
> > +   *new_mapping = false;
> > +
> >     if (vaddr > TASK_SIZE || vaddr < PAGE_SIZE)
> >             return ERR_PTR(-EINVAL);
> >
> 
> Does this fix address the VMA leak scenario across fork chains? In v2,
> sashiko-bot raised a concern about inherited-but-not-tracked VMAs:
> 
> https://lore.kernel.org/bpf/[email protected]/
> 
> When VM_DONTCOPY is removed, child processes inherit trampoline VMAs
> but their tracking list (mm->uprobes_state.head_tramps) is empty. When
> the child executes a uprobe, get_uprobe_trampoline() fails to find the
> inherited VMA and creates a duplicate trampoline.
> 
> Child fork:
>   dup_mmap()
>     copies trampoline VMA to child
>   mm_init_uprobes_state()
>     initializes head_tramps as empty (parent's state not copied)
> 
> Child executes uprobe:
>   arch_uprobe_optimize()
>     get_uprobe_trampoline()
>       head_tramps is empty, fails to find inherited VMA
>       create_uprobe_trampoline()
>         find_nearest_trampoline() finds new unmapped area
>         installs second duplicate trampoline VMA
> 
> In a deep fork chain, each generation inherits all previous VMAs, has an
> empty head_tramps list, and creates a new VMA. Can this cause linear
> accumulation of redundant VMAs, eventually exhausting vm.max_map_count?
> 
> While this patch addresses unmapping failed optimization attempts, it
> does not prevent the inherited-but-not-tracked VMA leak scenario in fork
> chains.

there's not head_tramps list anymore, was removed by earlier:
      uprobes/x86: Remove struct uprobe_trampoline object

jirka

Reply via email to