On 06/30, syzbot wrote: > > syzbot has found a reproducer for the following issue on: > > HEAD commit: dc59e4fea9d8 Linux 7.2-rc1 > git tree: upstream > console output: https://syzkaller.appspot.com/x/log.txt?x=15c7d61c580000 > kernel config: https://syzkaller.appspot.com/x/.config?x=f9bf5d2bfae96234 > dashboard link: https://syzkaller.appspot.com/bug?extid=61ce80689253f42e6d80 > compiler: gcc (Debian 14.2.0-19) 14.2.0, GNU ld (GNU Binutils for > Debian) 2.44 > syz repro: https://syzkaller.appspot.com/x/repro.syz?x=12bbb11c580000 > C reproducer: https://syzkaller.appspot.com/x/repro.c?x=130bf4ea580000 > > Downloadable assets: > disk image (non-bootable): > https://storage.googleapis.com/syzbot-assets/d900f083ada3/non_bootable_disk-dc59e4fe.raw.xz > vmlinux: > https://storage.googleapis.com/syzbot-assets/1bc8aed8d2e8/vmlinux-dc59e4fe.xz > kernel image: > https://storage.googleapis.com/syzbot-assets/0b1fdfc4aa09/bzImage-dc59e4fe.xz > > IMPORTANT: if you fix the issue, please add the following tag to the commit: > Reported-by: [email protected] > > Oops: general protection fault, probably for non-canonical address > 0xdffffc0000000011: 0000 [#1] SMP KASAN NOPTI
#syz test From: Jiri Olsa <[email protected]> In the unregister path we use __in_uprobe_trampoline check with current->mm for the VMA lookup, which is wrong, because we are in the tracer context, not the traced process. Add mm_struct pointer argument to __in_uprobe_trampoline and changing related callers to pass proper mm_struct pointer. Fixes: ba2bfc97b462 ("uprobes/x86: Add support to optimize uprobes") Acked-by: Andrii Nakryiko <[email protected]> Signed-off-by: Jiri Olsa <[email protected]> --- arch/x86/kernel/uprobes.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c index ebb1baf1eb1d..2be6707e3320 100644 --- a/arch/x86/kernel/uprobes.c +++ b/arch/x86/kernel/uprobes.c @@ -761,9 +761,9 @@ void arch_uprobe_clear_state(struct mm_struct *mm) destroy_uprobe_trampoline(tramp); } -static bool __in_uprobe_trampoline(unsigned long ip) +static bool __in_uprobe_trampoline(struct mm_struct *mm, unsigned long ip) { - struct vm_area_struct *vma = vma_lookup(current->mm, ip); + struct vm_area_struct *vma = vma_lookup(mm, ip); return vma && vma_is_special_mapping(vma, &tramp_mapping); } @@ -776,14 +776,14 @@ static bool in_uprobe_trampoline(unsigned long ip) rcu_read_lock(); if (mmap_lock_speculate_try_begin(mm, &seq)) { - found = __in_uprobe_trampoline(ip); + found = __in_uprobe_trampoline(mm, ip); retry = mmap_lock_speculate_retry(mm, seq); } rcu_read_unlock(); if (retry) { mmap_read_lock(mm); - found = __in_uprobe_trampoline(ip); + found = __in_uprobe_trampoline(mm, ip); mmap_read_unlock(mm); } return found; @@ -1044,7 +1044,7 @@ static int copy_from_vaddr(struct mm_struct *mm, unsigned long vaddr, void *dst, return 0; } -static bool __is_optimized(uprobe_opcode_t *insn, unsigned long vaddr) +static bool __is_optimized(struct mm_struct *mm, uprobe_opcode_t *insn, unsigned long vaddr) { struct __packed __arch_relative_insn { u8 op; @@ -1053,7 +1053,7 @@ static bool __is_optimized(uprobe_opcode_t *insn, unsigned long vaddr) if (!is_call_insn(insn)) return false; - return __in_uprobe_trampoline(vaddr + 5 + call->raddr); + return __in_uprobe_trampoline(mm, vaddr + 5 + call->raddr); } static int is_optimized(struct mm_struct *mm, unsigned long vaddr) @@ -1064,7 +1064,7 @@ static int is_optimized(struct mm_struct *mm, unsigned long vaddr) err = copy_from_vaddr(mm, vaddr, &insn, 5); if (err) return err; - return __is_optimized((uprobe_opcode_t *)&insn, vaddr); + return __is_optimized(mm, (uprobe_opcode_t *)&insn, vaddr); } static bool should_optimize(struct arch_uprobe *auprobe) -- 2.54.0
