On Wed, Jun 24, 2026 at 04:36:23PM +0200, Oleg Nesterov wrote:
> On 05/26, Jiri Olsa wrote:
> >
> > Removing struct uprobe_trampoline object and it's tracking code,
> > because it's not needed. We can do same thing directly on top of
> > struct vm_area_struct objects.
> >
> > This makes the code simpler and allows easy propagation of the
> > trampoline vma object into child process in following change.
> >
> > Note the original code called destroy_uprobe_trampoline if the
> > optimiation failed, but it only freed the struct uprobe_trampoline
> > object, not the vma. The new vma leak is fixed in following change.
> >
> > Acked-by: Andrii Nakryiko <[email protected]>
> > Signed-off-by: Jiri Olsa <[email protected]>
> 
> Reviewed-by: Oleg Nesterov <[email protected]>
> 
> ---------------------------------------------------------------------
> Although I can't convince myself I fully understand this code with or
> without this patch ;)
> 
> A couple of questions below...
> 
> > -static struct uprobe_trampoline *create_uprobe_trampoline(unsigned long 
> > vaddr)
> > +static struct vm_area_struct *get_uprobe_trampoline(struct mm_struct *mm, 
> > unsigned long vaddr)
> >  {
> > -   struct pt_regs *regs = task_pt_regs(current);
> > -   struct mm_struct *mm = current->mm;
> > -   struct uprobe_trampoline *tramp;
> > +   VMA_ITERATOR(vmi, mm, 0);
> >     struct vm_area_struct *vma;
> >
> > -   if (!user_64bit_mode(regs))
> > -           return NULL;
> > +   if (vaddr > TASK_SIZE || vaddr < PAGE_SIZE)
> > +           return ERR_PTR(-EINVAL);
> 
> Do we really need this check? It looks a bit confusing to me...
> vaddr is bp_vaddr from handle_swbp(), it should be valid?

true, will remove

> 
> > +
> > +   for_each_vma(vmi, vma) {
> > +           if (!vma_is_special_mapping(vma, &tramp_mapping))
> > +                   continue;
> > +           if (is_reachable_by_call(vma->vm_start, vaddr))
> > +                   return vma;
> > +   }
> 
> Perhaps we can later optimize this code a bit? I mean something like
> 
>       start_reachable = ...;
>       end_reachable = ...;
> 
>       VMA_ITERATOR(vmi, mm, start_reachable);
> 
>       for_each_vma(vmi, vma) {
>               if (!vma_is_special_mapping(...))
>                       continue;
>               if (vma->vm_start > end_reachable)
>                       break;
>               return vma;
>       }

looks good, will try to use that

> 
> >  static int __arch_uprobe_optimize(struct arch_uprobe *auprobe, struct 
> > mm_struct *mm,
> >                               unsigned long vaddr)
> >  {
> > -   struct uprobe_trampoline *tramp;
> > -   struct vm_area_struct *vma;
> > -   bool new = false;
> > -   int err = 0;
> > +   struct pt_regs *regs = task_pt_regs(current);
> > +   struct vm_area_struct *vma, *tramp;
> >
> > +   if (!user_64bit_mode(regs))
> > +           return -EINVAL;
> >     vma = find_vma(mm, vaddr);
> >     if (!vma)
> >             return -EINVAL;
> 
> I guess find_vma() can't fail, the caller arch_uprobe_optimize() has called
> copy_from_vaddr() under mmap_write_lock()... Nevermind.

hum, how's that.. I'll check, but where's the magic? :)

thanks,
jirka

Reply via email to