mirror of
https://github.com/torvalds/linux.git
synced 2026-09-23 05:04:02 +02:00
uprobes/x86: Do not leak trampoline vma mapping on optimization failure
In case the optimization fails, we leak new-ly created trampoline
vma mapping (in case we just created it), let's unmap it.
Fixes: ba2bfc97b4 ("uprobes/x86: Add support to optimize uprobes")
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Oleg Nesterov <oleg@redhat.com>
Link: https://patch.msgid.link/20260703114917.238144-4-jolsa@kernel.org
This commit is contained in:
parent
38af0dd6a2
commit
07c308eb2b
|
|
@ -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);
|
||||
|
||||
|
|
@ -696,6 +699,7 @@ static struct vm_area_struct *get_uprobe_trampoline(struct mm_struct *mm, unsign
|
|||
if (IS_ERR_VALUE(vaddr))
|
||||
return ERR_PTR(vaddr);
|
||||
|
||||
*new_mapping = true;
|
||||
return _install_special_mapping(mm, vaddr, PAGE_SIZE,
|
||||
VM_READ|VM_EXEC|VM_MAYEXEC|VM_MAYREAD|VM_DONTCOPY|VM_IO,
|
||||
&tramp_mapping);
|
||||
|
|
@ -1053,6 +1057,7 @@ static int __arch_uprobe_optimize(struct arch_uprobe *auprobe, struct mm_struct
|
|||
{
|
||||
struct pt_regs *regs = task_pt_regs(current);
|
||||
struct vm_area_struct *vma, *tramp;
|
||||
bool new_mapping;
|
||||
int ret;
|
||||
|
||||
if (!user_64bit_mode(regs))
|
||||
|
|
@ -1060,10 +1065,13 @@ static int __arch_uprobe_optimize(struct arch_uprobe *auprobe, struct mm_struct
|
|||
vma = find_vma(mm, vaddr);
|
||||
if (!vma)
|
||||
return -EINVAL;
|
||||
tramp = get_uprobe_trampoline(mm, vaddr);
|
||||
tramp = get_uprobe_trampoline(mm, vaddr, &new_mapping);
|
||||
if (IS_ERR(tramp))
|
||||
return PTR_ERR(tramp);
|
||||
return WARN_ON_ONCE(swbp_optimize(auprobe, vma, vaddr, tramp->vm_start));
|
||||
ret = swbp_optimize(auprobe, vma, vaddr, tramp->vm_start);
|
||||
if (WARN_ON_ONCE(ret) && new_mapping)
|
||||
WARN_ON_ONCE(do_munmap(mm, tramp->vm_start, PAGE_SIZE, NULL));
|
||||
return ret;
|
||||
}
|
||||
|
||||
void arch_uprobe_optimize(struct arch_uprobe *auprobe, unsigned long vaddr)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user