^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * User-space Probes (UProbes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) IBM Corporation, 2008-2012
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Authors:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Srikar Dronamraju
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Jim Keniston
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Copyright (C) 2011-2012 Red Hat, Inc., Peter Zijlstra
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/highmem.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/pagemap.h> /* read_mapping_page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/sched/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/sched/coredump.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/rmap.h> /* anon_vma_prepare */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/mmu_notifier.h> /* set_pte_at_notify */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/swap.h> /* try_to_free_swap */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/ptrace.h> /* user_enable_single_step */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/kdebug.h> /* notifier mechanism */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include "../../mm/internal.h" /* munlock_vma_page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/percpu-rwsem.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/task_work.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/shmem_fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/khugepaged.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/uprobes.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define UINSNS_PER_PAGE (PAGE_SIZE/UPROBE_XOL_SLOT_BYTES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define MAX_UPROBE_XOL_SLOTS UINSNS_PER_PAGE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) static struct rb_root uprobes_tree = RB_ROOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * allows us to skip the uprobe_mmap if there are no uprobe events active
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * at this time. Probably a fine grained per inode count is better?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define no_uprobe_events() RB_EMPTY_ROOT(&uprobes_tree)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) static DEFINE_SPINLOCK(uprobes_treelock); /* serialize rbtree access */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define UPROBES_HASH_SZ 13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) /* serialize uprobe->pending_list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) static struct mutex uprobes_mmap_mutex[UPROBES_HASH_SZ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define uprobes_mmap_hash(v) (&uprobes_mmap_mutex[((unsigned long)(v)) % UPROBES_HASH_SZ])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) DEFINE_STATIC_PERCPU_RWSEM(dup_mmap_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) /* Have a copy of original instruction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define UPROBE_COPY_INSN 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) struct uprobe {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) struct rb_node rb_node; /* node in the rb tree */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) refcount_t ref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) struct rw_semaphore register_rwsem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) struct rw_semaphore consumer_rwsem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) struct list_head pending_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) struct uprobe_consumer *consumers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) struct inode *inode; /* Also hold a ref to inode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) loff_t offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) loff_t ref_ctr_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * The generic code assumes that it has two members of unknown type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) * owned by the arch-specific code:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) * insn - copy_insn() saves the original instruction here for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * arch_uprobe_analyze_insn().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * ixol - potentially modified instruction to execute out of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * line, copied to xol_area by xol_get_insn_slot().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) struct arch_uprobe arch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) struct delayed_uprobe {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) struct list_head list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) struct uprobe *uprobe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct mm_struct *mm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) static DEFINE_MUTEX(delayed_uprobe_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) static LIST_HEAD(delayed_uprobe_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * Execute out of line area: anonymous executable mapping installed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) * by the probed task to execute the copy of the original instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * mangled by set_swbp().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) * On a breakpoint hit, thread contests for a slot. It frees the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * slot after singlestep. Currently a fixed number of slots are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) * allocated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) struct xol_area {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) wait_queue_head_t wq; /* if all slots are busy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) atomic_t slot_count; /* number of in-use slots */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) unsigned long *bitmap; /* 0 = free slot */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) struct vm_special_mapping xol_mapping;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) struct page *pages[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * We keep the vma's vm_start rather than a pointer to the vma
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * itself. The probed process or a naughty kernel module could make
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * the vma go away, and we must handle that reasonably gracefully.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) unsigned long vaddr; /* Page(s) of instruction slots */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) * valid_vma: Verify if the specified vma is an executable vma
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * Relax restrictions while unregistering: vm_flags might have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * changed after breakpoint was inserted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * - is_register: indicates if we are in register context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) * - Return 1 if the specified virtual address is in an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) * executable vma.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) static bool valid_vma(struct vm_area_struct *vma, bool is_register)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) vm_flags_t flags = VM_HUGETLB | VM_MAYEXEC | VM_MAYSHARE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) if (is_register)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) flags |= VM_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) return vma->vm_file && (vma->vm_flags & flags) == VM_MAYEXEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) static unsigned long offset_to_vaddr(struct vm_area_struct *vma, loff_t offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) return vma->vm_start + offset - ((loff_t)vma->vm_pgoff << PAGE_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) static loff_t vaddr_to_offset(struct vm_area_struct *vma, unsigned long vaddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) return ((loff_t)vma->vm_pgoff << PAGE_SHIFT) + (vaddr - vma->vm_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * __replace_page - replace page in vma by new page.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * based on replace_page in mm/ksm.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * @vma: vma that holds the pte pointing to page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) * @addr: address the old @page is mapped at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) * @old_page: the page we are replacing by new_page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) * @new_page: the modified page we replace page by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) * If @new_page is NULL, only unmap @old_page.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) * Returns 0 on success, negative error code otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) static int __replace_page(struct vm_area_struct *vma, unsigned long addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) struct page *old_page, struct page *new_page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) struct mm_struct *mm = vma->vm_mm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) struct page_vma_mapped_walk pvmw = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) .page = compound_head(old_page),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) .vma = vma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) .address = addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) struct mmu_notifier_range range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) mmu_notifier_range_init(&range, MMU_NOTIFY_CLEAR, 0, vma, mm, addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) addr + PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) if (new_page) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) err = mem_cgroup_charge(new_page, vma->vm_mm, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) /* For try_to_free_swap() and munlock_vma_page() below */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) lock_page(old_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) mmu_notifier_invalidate_range_start(&range);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) err = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) if (!page_vma_mapped_walk(&pvmw))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) VM_BUG_ON_PAGE(addr != pvmw.address, old_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) if (new_page) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) get_page(new_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) page_add_new_anon_rmap(new_page, vma, addr, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) lru_cache_add_inactive_or_unevictable(new_page, vma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) /* no new page, just dec_mm_counter for old_page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) dec_mm_counter(mm, MM_ANONPAGES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) if (!PageAnon(old_page)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) dec_mm_counter(mm, mm_counter_file(old_page));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) inc_mm_counter(mm, MM_ANONPAGES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) flush_cache_page(vma, addr, pte_pfn(*pvmw.pte));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) ptep_clear_flush_notify(vma, addr, pvmw.pte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) if (new_page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) set_pte_at_notify(mm, addr, pvmw.pte,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) mk_pte(new_page, vma->vm_page_prot));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) page_remove_rmap(old_page, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) if (!page_mapped(old_page))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) try_to_free_swap(old_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) page_vma_mapped_walk_done(&pvmw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) if ((vma->vm_flags & VM_LOCKED) && !PageCompound(old_page))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) munlock_vma_page(old_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) put_page(old_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) mmu_notifier_invalidate_range_end(&range);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) unlock_page(old_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) * is_swbp_insn - check if instruction is breakpoint instruction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) * @insn: instruction to be checked.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) * Default implementation of is_swbp_insn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) * Returns true if @insn is a breakpoint instruction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) bool __weak is_swbp_insn(uprobe_opcode_t *insn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) return *insn == UPROBE_SWBP_INSN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) * is_trap_insn - check if instruction is breakpoint instruction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) * @insn: instruction to be checked.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) * Default implementation of is_trap_insn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) * Returns true if @insn is a breakpoint instruction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) * This function is needed for the case where an architecture has multiple
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) * trap instructions (like powerpc).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) bool __weak is_trap_insn(uprobe_opcode_t *insn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) return is_swbp_insn(insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) static void copy_from_page(struct page *page, unsigned long vaddr, void *dst, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) void *kaddr = kmap_atomic(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) memcpy(dst, kaddr + (vaddr & ~PAGE_MASK), len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) kunmap_atomic(kaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) static void copy_to_page(struct page *page, unsigned long vaddr, const void *src, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) void *kaddr = kmap_atomic(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) memcpy(kaddr + (vaddr & ~PAGE_MASK), src, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) kunmap_atomic(kaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) static int verify_opcode(struct page *page, unsigned long vaddr, uprobe_opcode_t *new_opcode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) uprobe_opcode_t old_opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) bool is_swbp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) * Note: We only check if the old_opcode is UPROBE_SWBP_INSN here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) * We do not check if it is any other 'trap variant' which could
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) * be conditional trap instruction such as the one powerpc supports.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) * The logic is that we do not care if the underlying instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) * is a trap variant; uprobes always wins over any other (gdb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) * breakpoint.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) copy_from_page(page, vaddr, &old_opcode, UPROBE_SWBP_INSN_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) is_swbp = is_swbp_insn(&old_opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) if (is_swbp_insn(new_opcode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) if (is_swbp) /* register: already installed? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) if (!is_swbp) /* unregister: was it changed by us? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) static struct delayed_uprobe *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) delayed_uprobe_check(struct uprobe *uprobe, struct mm_struct *mm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) struct delayed_uprobe *du;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) list_for_each_entry(du, &delayed_uprobe_list, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) if (du->uprobe == uprobe && du->mm == mm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) return du;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) static int delayed_uprobe_add(struct uprobe *uprobe, struct mm_struct *mm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) struct delayed_uprobe *du;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) if (delayed_uprobe_check(uprobe, mm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) du = kzalloc(sizeof(*du), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) if (!du)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) du->uprobe = uprobe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) du->mm = mm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) list_add(&du->list, &delayed_uprobe_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) static void delayed_uprobe_delete(struct delayed_uprobe *du)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) if (WARN_ON(!du))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) list_del(&du->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) kfree(du);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) static void delayed_uprobe_remove(struct uprobe *uprobe, struct mm_struct *mm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) struct list_head *pos, *q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) struct delayed_uprobe *du;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) if (!uprobe && !mm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) list_for_each_safe(pos, q, &delayed_uprobe_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) du = list_entry(pos, struct delayed_uprobe, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) if (uprobe && du->uprobe != uprobe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) if (mm && du->mm != mm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) delayed_uprobe_delete(du);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) static bool valid_ref_ctr_vma(struct uprobe *uprobe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) struct vm_area_struct *vma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) unsigned long vaddr = offset_to_vaddr(vma, uprobe->ref_ctr_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) return uprobe->ref_ctr_offset &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) vma->vm_file &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) file_inode(vma->vm_file) == uprobe->inode &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) (vma->vm_flags & (VM_WRITE|VM_SHARED)) == VM_WRITE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) vma->vm_start <= vaddr &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) vma->vm_end > vaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) static struct vm_area_struct *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) find_ref_ctr_vma(struct uprobe *uprobe, struct mm_struct *mm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) struct vm_area_struct *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) for (tmp = mm->mmap; tmp; tmp = tmp->vm_next)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) if (valid_ref_ctr_vma(uprobe, tmp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) return tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) __update_ref_ctr(struct mm_struct *mm, unsigned long vaddr, short d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) void *kaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) struct page *page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) struct vm_area_struct *vma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) short *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) if (!vaddr || !d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) ret = get_user_pages_remote(mm, vaddr, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) FOLL_WRITE, &page, &vma, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) if (unlikely(ret <= 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) * We are asking for 1 page. If get_user_pages_remote() fails,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) * it may return 0, in that case we have to return error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) return ret == 0 ? -EBUSY : ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) kaddr = kmap_atomic(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) ptr = kaddr + (vaddr & ~PAGE_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) if (unlikely(*ptr + d < 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) pr_warn("ref_ctr going negative. vaddr: 0x%lx, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) "curr val: %d, delta: %d\n", vaddr, *ptr, d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) *ptr += d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) kunmap_atomic(kaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) put_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) static void update_ref_ctr_warn(struct uprobe *uprobe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) struct mm_struct *mm, short d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) pr_warn("ref_ctr %s failed for inode: 0x%lx offset: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) "0x%llx ref_ctr_offset: 0x%llx of mm: 0x%pK\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) d > 0 ? "increment" : "decrement", uprobe->inode->i_ino,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) (unsigned long long) uprobe->offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) (unsigned long long) uprobe->ref_ctr_offset, mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) static int update_ref_ctr(struct uprobe *uprobe, struct mm_struct *mm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) short d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) struct vm_area_struct *rc_vma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) unsigned long rc_vaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) rc_vma = find_ref_ctr_vma(uprobe, mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) if (rc_vma) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) rc_vaddr = offset_to_vaddr(rc_vma, uprobe->ref_ctr_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) ret = __update_ref_ctr(mm, rc_vaddr, d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) update_ref_ctr_warn(uprobe, mm, d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) if (d > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) mutex_lock(&delayed_uprobe_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) if (d > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) ret = delayed_uprobe_add(uprobe, mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) delayed_uprobe_remove(uprobe, mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) mutex_unlock(&delayed_uprobe_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) * NOTE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) * Expect the breakpoint instruction to be the smallest size instruction for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) * the architecture. If an arch has variable length instruction and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) * breakpoint instruction is not of the smallest length instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) * supported by that architecture then we need to modify is_trap_at_addr and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) * uprobe_write_opcode accordingly. This would never be a problem for archs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) * that have fixed length instructions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) * uprobe_write_opcode - write the opcode at a given virtual address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) * @mm: the probed process address space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) * @vaddr: the virtual address to store the opcode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) * @opcode: opcode to be written at @vaddr.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) * Called with mm->mmap_lock held for write.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) * Return 0 (success) or a negative errno.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) int uprobe_write_opcode(struct arch_uprobe *auprobe, struct mm_struct *mm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) unsigned long vaddr, uprobe_opcode_t opcode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) struct uprobe *uprobe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) struct page *old_page, *new_page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) struct vm_area_struct *vma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) int ret, is_register, ref_ctr_updated = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) bool orig_page_huge = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) unsigned int gup_flags = FOLL_FORCE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) is_register = is_swbp_insn(&opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) uprobe = container_of(auprobe, struct uprobe, arch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) retry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) if (is_register)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) gup_flags |= FOLL_SPLIT_PMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) /* Read the page with vaddr into memory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) ret = get_user_pages_remote(mm, vaddr, 1, gup_flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) &old_page, &vma, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) if (ret <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) ret = verify_opcode(old_page, vaddr, &opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) if (ret <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) goto put_old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) if (WARN(!is_register && PageCompound(old_page),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) "uprobe unregister should never work on compound page\n")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) goto put_old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) /* We are going to replace instruction, update ref_ctr. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) if (!ref_ctr_updated && uprobe->ref_ctr_offset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) ret = update_ref_ctr(uprobe, mm, is_register ? 1 : -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) goto put_old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) ref_ctr_updated = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) if (!is_register && !PageAnon(old_page))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) goto put_old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) ret = anon_vma_prepare(vma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) goto put_old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) new_page = alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma, vaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) if (!new_page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) goto put_old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) __SetPageUptodate(new_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) copy_highpage(new_page, old_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) copy_to_page(new_page, vaddr, &opcode, UPROBE_SWBP_INSN_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) if (!is_register) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) struct page *orig_page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) pgoff_t index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) VM_BUG_ON_PAGE(!PageAnon(old_page), old_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) index = vaddr_to_offset(vma, vaddr & PAGE_MASK) >> PAGE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) orig_page = find_get_page(vma->vm_file->f_inode->i_mapping,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) if (orig_page) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) if (PageUptodate(orig_page) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) pages_identical(new_page, orig_page)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) /* let go new_page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) put_page(new_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) new_page = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) if (PageCompound(orig_page))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) orig_page_huge = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) put_page(orig_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) ret = __replace_page(vma, vaddr, old_page, new_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) if (new_page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) put_page(new_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) put_old:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) put_page(old_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) if (unlikely(ret == -EAGAIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) goto retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) /* Revert back reference counter if instruction update failed. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) if (ret && is_register && ref_ctr_updated)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) update_ref_ctr(uprobe, mm, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) /* try collapse pmd for compound page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) if (!ret && orig_page_huge)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) collapse_pte_mapped_thp(mm, vaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) * set_swbp - store breakpoint at a given address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) * @auprobe: arch specific probepoint information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) * @mm: the probed process address space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) * @vaddr: the virtual address to insert the opcode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) * For mm @mm, store the breakpoint instruction at @vaddr.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) * Return 0 (success) or a negative errno.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) int __weak set_swbp(struct arch_uprobe *auprobe, struct mm_struct *mm, unsigned long vaddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) return uprobe_write_opcode(auprobe, mm, vaddr, UPROBE_SWBP_INSN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) * set_orig_insn - Restore the original instruction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) * @mm: the probed process address space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) * @auprobe: arch specific probepoint information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) * @vaddr: the virtual address to insert the opcode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) * For mm @mm, restore the original opcode (opcode) at @vaddr.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) * Return 0 (success) or a negative errno.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) int __weak
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) set_orig_insn(struct arch_uprobe *auprobe, struct mm_struct *mm, unsigned long vaddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) return uprobe_write_opcode(auprobe, mm, vaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) *(uprobe_opcode_t *)&auprobe->insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) static struct uprobe *get_uprobe(struct uprobe *uprobe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) refcount_inc(&uprobe->ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) return uprobe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) static void put_uprobe(struct uprobe *uprobe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) if (refcount_dec_and_test(&uprobe->ref)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) * If application munmap(exec_vma) before uprobe_unregister()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) * gets called, we don't get a chance to remove uprobe from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) * delayed_uprobe_list from remove_breakpoint(). Do it here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) mutex_lock(&delayed_uprobe_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) delayed_uprobe_remove(uprobe, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) mutex_unlock(&delayed_uprobe_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) kfree(uprobe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) static int match_uprobe(struct uprobe *l, struct uprobe *r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) if (l->inode < r->inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) if (l->inode > r->inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) if (l->offset < r->offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) if (l->offset > r->offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) static struct uprobe *__find_uprobe(struct inode *inode, loff_t offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) struct uprobe u = { .inode = inode, .offset = offset };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) struct rb_node *n = uprobes_tree.rb_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) struct uprobe *uprobe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) int match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) while (n) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) uprobe = rb_entry(n, struct uprobe, rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) match = match_uprobe(&u, uprobe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) if (!match)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) return get_uprobe(uprobe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) if (match < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) n = n->rb_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) n = n->rb_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) * Find a uprobe corresponding to a given inode:offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) * Acquires uprobes_treelock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) static struct uprobe *find_uprobe(struct inode *inode, loff_t offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) struct uprobe *uprobe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) spin_lock(&uprobes_treelock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) uprobe = __find_uprobe(inode, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) spin_unlock(&uprobes_treelock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) return uprobe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) static struct uprobe *__insert_uprobe(struct uprobe *uprobe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) struct rb_node **p = &uprobes_tree.rb_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) struct rb_node *parent = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) struct uprobe *u;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) int match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) while (*p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) parent = *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) u = rb_entry(parent, struct uprobe, rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) match = match_uprobe(uprobe, u);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) if (!match)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) return get_uprobe(u);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) if (match < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) p = &parent->rb_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) p = &parent->rb_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) u = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) rb_link_node(&uprobe->rb_node, parent, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) rb_insert_color(&uprobe->rb_node, &uprobes_tree);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) /* get access + creation ref */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) refcount_set(&uprobe->ref, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) return u;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) * Acquire uprobes_treelock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) * Matching uprobe already exists in rbtree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) * increment (access refcount) and return the matching uprobe.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) * No matching uprobe; insert the uprobe in rb_tree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) * get a double refcount (access + creation) and return NULL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) static struct uprobe *insert_uprobe(struct uprobe *uprobe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) struct uprobe *u;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) spin_lock(&uprobes_treelock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) u = __insert_uprobe(uprobe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) spin_unlock(&uprobes_treelock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) return u;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) ref_ctr_mismatch_warn(struct uprobe *cur_uprobe, struct uprobe *uprobe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) pr_warn("ref_ctr_offset mismatch. inode: 0x%lx offset: 0x%llx "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) "ref_ctr_offset(old): 0x%llx ref_ctr_offset(new): 0x%llx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) uprobe->inode->i_ino, (unsigned long long) uprobe->offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) (unsigned long long) cur_uprobe->ref_ctr_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) (unsigned long long) uprobe->ref_ctr_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) static struct uprobe *alloc_uprobe(struct inode *inode, loff_t offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) loff_t ref_ctr_offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) struct uprobe *uprobe, *cur_uprobe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) uprobe = kzalloc(sizeof(struct uprobe), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) if (!uprobe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) uprobe->inode = inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) uprobe->offset = offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) uprobe->ref_ctr_offset = ref_ctr_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) init_rwsem(&uprobe->register_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) init_rwsem(&uprobe->consumer_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) /* add to uprobes_tree, sorted on inode:offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) cur_uprobe = insert_uprobe(uprobe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) /* a uprobe exists for this inode:offset combination */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) if (cur_uprobe) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) if (cur_uprobe->ref_ctr_offset != uprobe->ref_ctr_offset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) ref_ctr_mismatch_warn(cur_uprobe, uprobe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) put_uprobe(cur_uprobe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) kfree(uprobe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) kfree(uprobe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) uprobe = cur_uprobe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) return uprobe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) static void consumer_add(struct uprobe *uprobe, struct uprobe_consumer *uc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) down_write(&uprobe->consumer_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) uc->next = uprobe->consumers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) uprobe->consumers = uc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) up_write(&uprobe->consumer_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) * For uprobe @uprobe, delete the consumer @uc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) * Return true if the @uc is deleted successfully
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) * or return false.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) static bool consumer_del(struct uprobe *uprobe, struct uprobe_consumer *uc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) struct uprobe_consumer **con;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) bool ret = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) down_write(&uprobe->consumer_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) for (con = &uprobe->consumers; *con; con = &(*con)->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) if (*con == uc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) *con = uc->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) ret = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) up_write(&uprobe->consumer_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) static int __copy_insn(struct address_space *mapping, struct file *filp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) void *insn, int nbytes, loff_t offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) struct page *page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) * Ensure that the page that has the original instruction is populated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) * and in page-cache. If ->readpage == NULL it must be shmem_mapping(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) * see uprobe_register().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) if (mapping->a_ops->readpage)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) page = read_mapping_page(mapping, offset >> PAGE_SHIFT, filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) page = shmem_read_mapping_page(mapping, offset >> PAGE_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) if (IS_ERR(page))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) return PTR_ERR(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) copy_from_page(page, offset, insn, nbytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) put_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) static int copy_insn(struct uprobe *uprobe, struct file *filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) struct address_space *mapping = uprobe->inode->i_mapping;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) loff_t offs = uprobe->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) void *insn = &uprobe->arch.insn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) int size = sizeof(uprobe->arch.insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) int len, err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) /* Copy only available bytes, -EIO if nothing was read */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) if (offs >= i_size_read(uprobe->inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) len = min_t(int, size, PAGE_SIZE - (offs & ~PAGE_MASK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) err = __copy_insn(mapping, filp, insn, len, offs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) insn += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) offs += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) size -= len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) } while (size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) static int prepare_uprobe(struct uprobe *uprobe, struct file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) struct mm_struct *mm, unsigned long vaddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) if (test_bit(UPROBE_COPY_INSN, &uprobe->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) /* TODO: move this into _register, until then we abuse this sem. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) down_write(&uprobe->consumer_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) if (test_bit(UPROBE_COPY_INSN, &uprobe->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) ret = copy_insn(uprobe, file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) ret = -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) if (is_trap_insn((uprobe_opcode_t *)&uprobe->arch.insn))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) ret = arch_uprobe_analyze_insn(&uprobe->arch, mm, vaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) smp_wmb(); /* pairs with the smp_rmb() in handle_swbp() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) set_bit(UPROBE_COPY_INSN, &uprobe->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) up_write(&uprobe->consumer_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) static inline bool consumer_filter(struct uprobe_consumer *uc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) enum uprobe_filter_ctx ctx, struct mm_struct *mm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) return !uc->filter || uc->filter(uc, ctx, mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) static bool filter_chain(struct uprobe *uprobe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) enum uprobe_filter_ctx ctx, struct mm_struct *mm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) struct uprobe_consumer *uc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) bool ret = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) down_read(&uprobe->consumer_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) for (uc = uprobe->consumers; uc; uc = uc->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) ret = consumer_filter(uc, ctx, mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) up_read(&uprobe->consumer_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) install_breakpoint(struct uprobe *uprobe, struct mm_struct *mm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) struct vm_area_struct *vma, unsigned long vaddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) bool first_uprobe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) ret = prepare_uprobe(uprobe, vma->vm_file, mm, vaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) * set MMF_HAS_UPROBES in advance for uprobe_pre_sstep_notifier(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) * the task can hit this breakpoint right after __replace_page().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) first_uprobe = !test_bit(MMF_HAS_UPROBES, &mm->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) if (first_uprobe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) set_bit(MMF_HAS_UPROBES, &mm->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) ret = set_swbp(&uprobe->arch, mm, vaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) clear_bit(MMF_RECALC_UPROBES, &mm->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) else if (first_uprobe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) clear_bit(MMF_HAS_UPROBES, &mm->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) remove_breakpoint(struct uprobe *uprobe, struct mm_struct *mm, unsigned long vaddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) set_bit(MMF_RECALC_UPROBES, &mm->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) return set_orig_insn(&uprobe->arch, mm, vaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) static inline bool uprobe_is_active(struct uprobe *uprobe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) return !RB_EMPTY_NODE(&uprobe->rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) * There could be threads that have already hit the breakpoint. They
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) * will recheck the current insn and restart if find_uprobe() fails.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) * See find_active_uprobe().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) static void delete_uprobe(struct uprobe *uprobe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) if (WARN_ON(!uprobe_is_active(uprobe)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) spin_lock(&uprobes_treelock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) rb_erase(&uprobe->rb_node, &uprobes_tree);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) spin_unlock(&uprobes_treelock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) RB_CLEAR_NODE(&uprobe->rb_node); /* for uprobe_is_active() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) put_uprobe(uprobe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) struct map_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) struct map_info *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) struct mm_struct *mm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) unsigned long vaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) static inline struct map_info *free_map_info(struct map_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) struct map_info *next = info->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) kfree(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) return next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) static struct map_info *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) build_map_info(struct address_space *mapping, loff_t offset, bool is_register)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) unsigned long pgoff = offset >> PAGE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) struct vm_area_struct *vma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) struct map_info *curr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) struct map_info *prev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) struct map_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) int more = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) again:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) i_mmap_lock_read(mapping);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) vma_interval_tree_foreach(vma, &mapping->i_mmap, pgoff, pgoff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) if (!valid_vma(vma, is_register))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) if (!prev && !more) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) * Needs GFP_NOWAIT to avoid i_mmap_rwsem recursion through
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) * reclaim. This is optimistic, no harm done if it fails.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) prev = kmalloc(sizeof(struct map_info),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) GFP_NOWAIT | __GFP_NOMEMALLOC | __GFP_NOWARN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) if (prev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) prev->next = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) if (!prev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) more++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) if (!mmget_not_zero(vma->vm_mm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) info = prev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) prev = prev->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) info->next = curr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) curr = info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) info->mm = vma->vm_mm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) info->vaddr = offset_to_vaddr(vma, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) i_mmap_unlock_read(mapping);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) if (!more)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) prev = curr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) while (curr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) mmput(curr->mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) curr = curr->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) info = kmalloc(sizeof(struct map_info), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) if (!info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) curr = ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) info->next = prev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) prev = info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) } while (--more);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) goto again;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) while (prev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) prev = free_map_info(prev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) return curr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) register_for_each_vma(struct uprobe *uprobe, struct uprobe_consumer *new)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) bool is_register = !!new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) struct map_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) percpu_down_write(&dup_mmap_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) info = build_map_info(uprobe->inode->i_mapping,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) uprobe->offset, is_register);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) if (IS_ERR(info)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) err = PTR_ERR(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) while (info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) struct mm_struct *mm = info->mm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) struct vm_area_struct *vma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) if (err && is_register)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) mmap_write_lock(mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) vma = find_vma(mm, info->vaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) if (!vma || !valid_vma(vma, is_register) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) file_inode(vma->vm_file) != uprobe->inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) if (vma->vm_start > info->vaddr ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) vaddr_to_offset(vma, info->vaddr) != uprobe->offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) if (is_register) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) /* consult only the "caller", new consumer. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) if (consumer_filter(new,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) UPROBE_FILTER_REGISTER, mm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) err = install_breakpoint(uprobe, mm, vma, info->vaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) } else if (test_bit(MMF_HAS_UPROBES, &mm->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) if (!filter_chain(uprobe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) UPROBE_FILTER_UNREGISTER, mm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) err |= remove_breakpoint(uprobe, mm, info->vaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) mmap_write_unlock(mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) mmput(mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) info = free_map_info(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) percpu_up_write(&dup_mmap_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) __uprobe_unregister(struct uprobe *uprobe, struct uprobe_consumer *uc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) if (WARN_ON(!consumer_del(uprobe, uc)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) err = register_for_each_vma(uprobe, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) /* TODO : cant unregister? schedule a worker thread */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) if (!uprobe->consumers && !err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) delete_uprobe(uprobe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) * uprobe_unregister - unregister an already registered probe.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) * @inode: the file in which the probe has to be removed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) * @offset: offset from the start of the file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) * @uc: identify which probe if multiple probes are colocated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) void uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consumer *uc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) struct uprobe *uprobe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) uprobe = find_uprobe(inode, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) if (WARN_ON(!uprobe))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) down_write(&uprobe->register_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) __uprobe_unregister(uprobe, uc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) up_write(&uprobe->register_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) put_uprobe(uprobe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) EXPORT_SYMBOL_GPL(uprobe_unregister);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) * __uprobe_register - register a probe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) * @inode: the file in which the probe has to be placed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) * @offset: offset from the start of the file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) * @uc: information on howto handle the probe..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) * Apart from the access refcount, __uprobe_register() takes a creation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) * refcount (thro alloc_uprobe) if and only if this @uprobe is getting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) * inserted into the rbtree (i.e first consumer for a @inode:@offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) * tuple). Creation refcount stops uprobe_unregister from freeing the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) * @uprobe even before the register operation is complete. Creation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) * refcount is released when the last @uc for the @uprobe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) * unregisters. Caller of __uprobe_register() is required to keep @inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) * (and the containing mount) referenced.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) * Return errno if it cannot successully install probes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) * else return 0 (success)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) static int __uprobe_register(struct inode *inode, loff_t offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) loff_t ref_ctr_offset, struct uprobe_consumer *uc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) struct uprobe *uprobe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) /* Uprobe must have at least one set consumer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) if (!uc->handler && !uc->ret_handler)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) /* copy_insn() uses read_mapping_page() or shmem_read_mapping_page() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) if (!inode->i_mapping->a_ops->readpage && !shmem_mapping(inode->i_mapping))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) /* Racy, just to catch the obvious mistakes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) if (offset > i_size_read(inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) * This ensures that copy_from_page(), copy_to_page() and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) * __update_ref_ctr() can't cross page boundary.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) if (!IS_ALIGNED(offset, UPROBE_SWBP_INSN_SIZE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) if (!IS_ALIGNED(ref_ctr_offset, sizeof(short)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) retry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) uprobe = alloc_uprobe(inode, offset, ref_ctr_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) if (!uprobe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) if (IS_ERR(uprobe))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) return PTR_ERR(uprobe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) * We can race with uprobe_unregister()->delete_uprobe().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) * Check uprobe_is_active() and retry if it is false.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) down_write(&uprobe->register_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) ret = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) if (likely(uprobe_is_active(uprobe))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) consumer_add(uprobe, uc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) ret = register_for_each_vma(uprobe, uc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) __uprobe_unregister(uprobe, uc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) up_write(&uprobe->register_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) put_uprobe(uprobe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) if (unlikely(ret == -EAGAIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) goto retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) int uprobe_register(struct inode *inode, loff_t offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) struct uprobe_consumer *uc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) return __uprobe_register(inode, offset, 0, uc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) EXPORT_SYMBOL_GPL(uprobe_register);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) int uprobe_register_refctr(struct inode *inode, loff_t offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) loff_t ref_ctr_offset, struct uprobe_consumer *uc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) return __uprobe_register(inode, offset, ref_ctr_offset, uc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) EXPORT_SYMBOL_GPL(uprobe_register_refctr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) * uprobe_apply - unregister an already registered probe.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) * @inode: the file in which the probe has to be removed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) * @offset: offset from the start of the file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) * @uc: consumer which wants to add more or remove some breakpoints
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) * @add: add or remove the breakpoints
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) int uprobe_apply(struct inode *inode, loff_t offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) struct uprobe_consumer *uc, bool add)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) struct uprobe *uprobe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) struct uprobe_consumer *con;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) int ret = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) uprobe = find_uprobe(inode, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) if (WARN_ON(!uprobe))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) down_write(&uprobe->register_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) for (con = uprobe->consumers; con && con != uc ; con = con->next)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) if (con)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) ret = register_for_each_vma(uprobe, add ? uc : NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) up_write(&uprobe->register_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) put_uprobe(uprobe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) static int unapply_uprobe(struct uprobe *uprobe, struct mm_struct *mm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) struct vm_area_struct *vma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) mmap_read_lock(mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) for (vma = mm->mmap; vma; vma = vma->vm_next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) unsigned long vaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) loff_t offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) if (!valid_vma(vma, false) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) file_inode(vma->vm_file) != uprobe->inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) offset = (loff_t)vma->vm_pgoff << PAGE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) if (uprobe->offset < offset ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) uprobe->offset >= offset + vma->vm_end - vma->vm_start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) vaddr = offset_to_vaddr(vma, uprobe->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) err |= remove_breakpoint(uprobe, mm, vaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) mmap_read_unlock(mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) static struct rb_node *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) find_node_in_range(struct inode *inode, loff_t min, loff_t max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) struct rb_node *n = uprobes_tree.rb_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) while (n) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) struct uprobe *u = rb_entry(n, struct uprobe, rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) if (inode < u->inode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) n = n->rb_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) } else if (inode > u->inode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) n = n->rb_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) if (max < u->offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) n = n->rb_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) else if (min > u->offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) n = n->rb_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) return n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) * For a given range in vma, build a list of probes that need to be inserted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) static void build_probe_list(struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) struct vm_area_struct *vma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) unsigned long start, unsigned long end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) struct list_head *head)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) loff_t min, max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) struct rb_node *n, *t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) struct uprobe *u;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) INIT_LIST_HEAD(head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) min = vaddr_to_offset(vma, start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) max = min + (end - start) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) spin_lock(&uprobes_treelock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) n = find_node_in_range(inode, min, max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) if (n) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) for (t = n; t; t = rb_prev(t)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) u = rb_entry(t, struct uprobe, rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) if (u->inode != inode || u->offset < min)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) list_add(&u->pending_list, head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) get_uprobe(u);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) for (t = n; (t = rb_next(t)); ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) u = rb_entry(t, struct uprobe, rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) if (u->inode != inode || u->offset > max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) list_add(&u->pending_list, head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) get_uprobe(u);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) spin_unlock(&uprobes_treelock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) /* @vma contains reference counter, not the probed instruction. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) static int delayed_ref_ctr_inc(struct vm_area_struct *vma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) struct list_head *pos, *q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) struct delayed_uprobe *du;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) unsigned long vaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) int ret = 0, err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) mutex_lock(&delayed_uprobe_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) list_for_each_safe(pos, q, &delayed_uprobe_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) du = list_entry(pos, struct delayed_uprobe, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) if (du->mm != vma->vm_mm ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) !valid_ref_ctr_vma(du->uprobe, vma))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) vaddr = offset_to_vaddr(vma, du->uprobe->ref_ctr_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) ret = __update_ref_ctr(vma->vm_mm, vaddr, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) update_ref_ctr_warn(du->uprobe, vma->vm_mm, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) err = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) delayed_uprobe_delete(du);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) mutex_unlock(&delayed_uprobe_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) * Called from mmap_region/vma_adjust with mm->mmap_lock acquired.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) * Currently we ignore all errors and always return 0, the callers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) * can't handle the failure anyway.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) int uprobe_mmap(struct vm_area_struct *vma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) struct list_head tmp_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) struct uprobe *uprobe, *u;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) if (no_uprobe_events())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) if (vma->vm_file &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) (vma->vm_flags & (VM_WRITE|VM_SHARED)) == VM_WRITE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) test_bit(MMF_HAS_UPROBES, &vma->vm_mm->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) delayed_ref_ctr_inc(vma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) if (!valid_vma(vma, true))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) inode = file_inode(vma->vm_file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) if (!inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) mutex_lock(uprobes_mmap_hash(inode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) build_probe_list(inode, vma, vma->vm_start, vma->vm_end, &tmp_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) * We can race with uprobe_unregister(), this uprobe can be already
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) * removed. But in this case filter_chain() must return false, all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) * consumers have gone away.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) list_for_each_entry_safe(uprobe, u, &tmp_list, pending_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) if (!fatal_signal_pending(current) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) filter_chain(uprobe, UPROBE_FILTER_MMAP, vma->vm_mm)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) unsigned long vaddr = offset_to_vaddr(vma, uprobe->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) install_breakpoint(uprobe, vma->vm_mm, vma, vaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) put_uprobe(uprobe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) mutex_unlock(uprobes_mmap_hash(inode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) vma_has_uprobes(struct vm_area_struct *vma, unsigned long start, unsigned long end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) loff_t min, max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) struct rb_node *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) inode = file_inode(vma->vm_file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) min = vaddr_to_offset(vma, start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) max = min + (end - start) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) spin_lock(&uprobes_treelock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) n = find_node_in_range(inode, min, max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) spin_unlock(&uprobes_treelock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) return !!n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) * Called in context of a munmap of a vma.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) void uprobe_munmap(struct vm_area_struct *vma, unsigned long start, unsigned long end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) if (no_uprobe_events() || !valid_vma(vma, false))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) if (!atomic_read(&vma->vm_mm->mm_users)) /* called by mmput() ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) if (!test_bit(MMF_HAS_UPROBES, &vma->vm_mm->flags) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) test_bit(MMF_RECALC_UPROBES, &vma->vm_mm->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) if (vma_has_uprobes(vma, start, end))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) set_bit(MMF_RECALC_UPROBES, &vma->vm_mm->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) /* Slot allocation for XOL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) static int xol_add_vma(struct mm_struct *mm, struct xol_area *area)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) struct vm_area_struct *vma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) if (mmap_write_lock_killable(mm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) return -EINTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) if (mm->uprobes_state.xol_area) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) ret = -EALREADY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) if (!area->vaddr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) /* Try to map as high as possible, this is only a hint. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) area->vaddr = get_unmapped_area(NULL, TASK_SIZE - PAGE_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) PAGE_SIZE, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) if (IS_ERR_VALUE(area->vaddr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) ret = area->vaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) vma = _install_special_mapping(mm, area->vaddr, PAGE_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) VM_EXEC|VM_MAYEXEC|VM_DONTCOPY|VM_IO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) &area->xol_mapping);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) if (IS_ERR(vma)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) ret = PTR_ERR(vma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) /* pairs with get_xol_area() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) smp_store_release(&mm->uprobes_state.xol_area, area); /* ^^^ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) mmap_write_unlock(mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) static struct xol_area *__create_xol_area(unsigned long vaddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) struct mm_struct *mm = current->mm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) uprobe_opcode_t insn = UPROBE_SWBP_INSN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) struct xol_area *area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) area = kmalloc(sizeof(*area), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) if (unlikely(!area))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) area->bitmap = kcalloc(BITS_TO_LONGS(UINSNS_PER_PAGE), sizeof(long),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) if (!area->bitmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) goto free_area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) area->xol_mapping.name = "[uprobes]";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) area->xol_mapping.fault = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) area->xol_mapping.pages = area->pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) area->pages[0] = alloc_page(GFP_HIGHUSER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) if (!area->pages[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) goto free_bitmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) area->pages[1] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) area->vaddr = vaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) init_waitqueue_head(&area->wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) /* Reserve the 1st slot for get_trampoline_vaddr() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) set_bit(0, area->bitmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) atomic_set(&area->slot_count, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) arch_uprobe_copy_ixol(area->pages[0], 0, &insn, UPROBE_SWBP_INSN_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) if (!xol_add_vma(mm, area))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) return area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) __free_page(area->pages[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) free_bitmap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) kfree(area->bitmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) free_area:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) kfree(area);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) * get_xol_area - Allocate process's xol_area if necessary.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) * This area will be used for storing instructions for execution out of line.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) * Returns the allocated area or NULL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) static struct xol_area *get_xol_area(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) struct mm_struct *mm = current->mm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) struct xol_area *area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) if (!mm->uprobes_state.xol_area)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) __create_xol_area(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) /* Pairs with xol_add_vma() smp_store_release() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) area = READ_ONCE(mm->uprobes_state.xol_area); /* ^^^ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) return area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) * uprobe_clear_state - Free the area allocated for slots.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) void uprobe_clear_state(struct mm_struct *mm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) struct xol_area *area = mm->uprobes_state.xol_area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) mutex_lock(&delayed_uprobe_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) delayed_uprobe_remove(NULL, mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) mutex_unlock(&delayed_uprobe_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) if (!area)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) put_page(area->pages[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) kfree(area->bitmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) kfree(area);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) void uprobe_start_dup_mmap(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) percpu_down_read(&dup_mmap_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) void uprobe_end_dup_mmap(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) percpu_up_read(&dup_mmap_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) void uprobe_dup_mmap(struct mm_struct *oldmm, struct mm_struct *newmm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) if (test_bit(MMF_HAS_UPROBES, &oldmm->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) set_bit(MMF_HAS_UPROBES, &newmm->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) /* unconditionally, dup_mmap() skips VM_DONTCOPY vmas */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) set_bit(MMF_RECALC_UPROBES, &newmm->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) * - search for a free slot.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) static unsigned long xol_take_insn_slot(struct xol_area *area)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) unsigned long slot_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) int slot_nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) slot_nr = find_first_zero_bit(area->bitmap, UINSNS_PER_PAGE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) if (slot_nr < UINSNS_PER_PAGE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) if (!test_and_set_bit(slot_nr, area->bitmap))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) slot_nr = UINSNS_PER_PAGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) wait_event(area->wq, (atomic_read(&area->slot_count) < UINSNS_PER_PAGE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) } while (slot_nr >= UINSNS_PER_PAGE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) slot_addr = area->vaddr + (slot_nr * UPROBE_XOL_SLOT_BYTES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) atomic_inc(&area->slot_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) return slot_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) * xol_get_insn_slot - allocate a slot for xol.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) * Returns the allocated slot address or 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) static unsigned long xol_get_insn_slot(struct uprobe *uprobe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) struct xol_area *area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) unsigned long xol_vaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) area = get_xol_area();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) if (!area)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) xol_vaddr = xol_take_insn_slot(area);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) if (unlikely(!xol_vaddr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) arch_uprobe_copy_ixol(area->pages[0], xol_vaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) &uprobe->arch.ixol, sizeof(uprobe->arch.ixol));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) return xol_vaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) * xol_free_insn_slot - If slot was earlier allocated by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) * @xol_get_insn_slot(), make the slot available for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) * subsequent requests.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) static void xol_free_insn_slot(struct task_struct *tsk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) struct xol_area *area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) unsigned long vma_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) unsigned long slot_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) if (!tsk->mm || !tsk->mm->uprobes_state.xol_area || !tsk->utask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) slot_addr = tsk->utask->xol_vaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) if (unlikely(!slot_addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) area = tsk->mm->uprobes_state.xol_area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) vma_end = area->vaddr + PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) if (area->vaddr <= slot_addr && slot_addr < vma_end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) unsigned long offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) int slot_nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) offset = slot_addr - area->vaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) slot_nr = offset / UPROBE_XOL_SLOT_BYTES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) if (slot_nr >= UINSNS_PER_PAGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) clear_bit(slot_nr, area->bitmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) atomic_dec(&area->slot_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) smp_mb__after_atomic(); /* pairs with prepare_to_wait() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) if (waitqueue_active(&area->wq))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) wake_up(&area->wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) tsk->utask->xol_vaddr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) void __weak arch_uprobe_copy_ixol(struct page *page, unsigned long vaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) void *src, unsigned long len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) /* Initialize the slot */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) copy_to_page(page, vaddr, src, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) * We probably need flush_icache_user_page() but it needs vma.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) * This should work on most of architectures by default. If
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) * architecture needs to do something different it can define
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) * its own version of the function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) flush_dcache_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) * uprobe_get_swbp_addr - compute address of swbp given post-swbp regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) * @regs: Reflects the saved state of the task after it has hit a breakpoint
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) * instruction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) * Return the address of the breakpoint instruction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) unsigned long __weak uprobe_get_swbp_addr(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) return instruction_pointer(regs) - UPROBE_SWBP_INSN_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) unsigned long uprobe_get_trap_addr(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) struct uprobe_task *utask = current->utask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) if (unlikely(utask && utask->active_uprobe))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) return utask->vaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) return instruction_pointer(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) static struct return_instance *free_ret_instance(struct return_instance *ri)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) struct return_instance *next = ri->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) put_uprobe(ri->uprobe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) kfree(ri);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) return next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) * Called with no locks held.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) * Called in context of an exiting or an exec-ing thread.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) void uprobe_free_utask(struct task_struct *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) struct uprobe_task *utask = t->utask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) struct return_instance *ri;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) if (!utask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) if (utask->active_uprobe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) put_uprobe(utask->active_uprobe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) ri = utask->return_instances;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) while (ri)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) ri = free_ret_instance(ri);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) xol_free_insn_slot(t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) kfree(utask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) t->utask = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) * Allocate a uprobe_task object for the task if necessary.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) * Called when the thread hits a breakpoint.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) * - pointer to new uprobe_task on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) * - NULL otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) static struct uprobe_task *get_utask(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) if (!current->utask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) current->utask = kzalloc(sizeof(struct uprobe_task), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) return current->utask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) static int dup_utask(struct task_struct *t, struct uprobe_task *o_utask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) struct uprobe_task *n_utask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) struct return_instance **p, *o, *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) n_utask = kzalloc(sizeof(struct uprobe_task), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) if (!n_utask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) t->utask = n_utask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) p = &n_utask->return_instances;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) for (o = o_utask->return_instances; o; o = o->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) n = kmalloc(sizeof(struct return_instance), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) if (!n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) *n = *o;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) get_uprobe(n->uprobe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) n->next = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) *p = n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) p = &n->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) n_utask->depth++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) static void uprobe_warn(struct task_struct *t, const char *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) pr_warn("uprobe: %s:%d failed to %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) current->comm, current->pid, msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) static void dup_xol_work(struct callback_head *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) if (current->flags & PF_EXITING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) if (!__create_xol_area(current->utask->dup_xol_addr) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) !fatal_signal_pending(current))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) uprobe_warn(current, "dup xol area");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) * Called in context of a new clone/fork from copy_process.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) void uprobe_copy_process(struct task_struct *t, unsigned long flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) struct uprobe_task *utask = current->utask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) struct mm_struct *mm = current->mm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) struct xol_area *area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) t->utask = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) if (!utask || !utask->return_instances)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) if (mm == t->mm && !(flags & CLONE_VFORK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) if (dup_utask(t, utask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) return uprobe_warn(t, "dup ret instances");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) /* The task can fork() after dup_xol_work() fails */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) area = mm->uprobes_state.xol_area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) if (!area)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) return uprobe_warn(t, "dup xol area");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) if (mm == t->mm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) t->utask->dup_xol_addr = area->vaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) init_task_work(&t->utask->dup_xol_work, dup_xol_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) task_work_add(t, &t->utask->dup_xol_work, TWA_RESUME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) * Current area->vaddr notion assume the trampoline address is always
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) * equal area->vaddr.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) * Returns -1 in case the xol_area is not allocated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) static unsigned long get_trampoline_vaddr(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) struct xol_area *area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) unsigned long trampoline_vaddr = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) /* Pairs with xol_add_vma() smp_store_release() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) area = READ_ONCE(current->mm->uprobes_state.xol_area); /* ^^^ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) if (area)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) trampoline_vaddr = area->vaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) return trampoline_vaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) static void cleanup_return_instances(struct uprobe_task *utask, bool chained,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) struct return_instance *ri = utask->return_instances;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) enum rp_check ctx = chained ? RP_CHECK_CHAIN_CALL : RP_CHECK_CALL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) while (ri && !arch_uretprobe_is_alive(ri, ctx, regs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) ri = free_ret_instance(ri);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) utask->depth--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) utask->return_instances = ri;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) static void prepare_uretprobe(struct uprobe *uprobe, struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) struct return_instance *ri;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) struct uprobe_task *utask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) unsigned long orig_ret_vaddr, trampoline_vaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) bool chained;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) if (!get_xol_area())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) utask = get_utask();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) if (!utask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) if (utask->depth >= MAX_URETPROBE_DEPTH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) printk_ratelimited(KERN_INFO "uprobe: omit uretprobe due to"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) " nestedness limit pid/tgid=%d/%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) current->pid, current->tgid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) ri = kmalloc(sizeof(struct return_instance), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) if (!ri)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) trampoline_vaddr = get_trampoline_vaddr();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) orig_ret_vaddr = arch_uretprobe_hijack_return_addr(trampoline_vaddr, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) if (orig_ret_vaddr == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) /* drop the entries invalidated by longjmp() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) chained = (orig_ret_vaddr == trampoline_vaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) cleanup_return_instances(utask, chained, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) * We don't want to keep trampoline address in stack, rather keep the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) * original return address of first caller thru all the consequent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) * instances. This also makes breakpoint unwrapping easier.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) if (chained) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) if (!utask->return_instances) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) * This situation is not possible. Likely we have an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) * attack from user-space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) uprobe_warn(current, "handle tail call");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) orig_ret_vaddr = utask->return_instances->orig_ret_vaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) ri->uprobe = get_uprobe(uprobe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) ri->func = instruction_pointer(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) ri->stack = user_stack_pointer(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) ri->orig_ret_vaddr = orig_ret_vaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) ri->chained = chained;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) utask->depth++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) ri->next = utask->return_instances;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) utask->return_instances = ri;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) kfree(ri);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) /* Prepare to single-step probed instruction out of line. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) pre_ssout(struct uprobe *uprobe, struct pt_regs *regs, unsigned long bp_vaddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) struct uprobe_task *utask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) unsigned long xol_vaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) utask = get_utask();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) if (!utask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) xol_vaddr = xol_get_insn_slot(uprobe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) if (!xol_vaddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) utask->xol_vaddr = xol_vaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) utask->vaddr = bp_vaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) err = arch_uprobe_pre_xol(&uprobe->arch, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) if (unlikely(err)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) xol_free_insn_slot(current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) utask->active_uprobe = uprobe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) utask->state = UTASK_SSTEP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) * If we are singlestepping, then ensure this thread is not connected to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) * non-fatal signals until completion of singlestep. When xol insn itself
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) * triggers the signal, restart the original insn even if the task is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) * already SIGKILL'ed (since coredump should report the correct ip). This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) * is even more important if the task has a handler for SIGSEGV/etc, The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) * _same_ instruction should be repeated again after return from the signal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) * handler, and SSTEP can never finish in this case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) bool uprobe_deny_signal(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) struct task_struct *t = current;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) struct uprobe_task *utask = t->utask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) if (likely(!utask || !utask->active_uprobe))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) WARN_ON_ONCE(utask->state != UTASK_SSTEP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) if (signal_pending(t)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) spin_lock_irq(&t->sighand->siglock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) clear_tsk_thread_flag(t, TIF_SIGPENDING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) spin_unlock_irq(&t->sighand->siglock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) if (__fatal_signal_pending(t) || arch_uprobe_xol_was_trapped(t)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) utask->state = UTASK_SSTEP_TRAPPED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) set_tsk_thread_flag(t, TIF_UPROBE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) static void mmf_recalc_uprobes(struct mm_struct *mm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) struct vm_area_struct *vma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) for (vma = mm->mmap; vma; vma = vma->vm_next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) if (!valid_vma(vma, false))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) * This is not strictly accurate, we can race with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) * uprobe_unregister() and see the already removed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) * uprobe if delete_uprobe() was not yet called.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) * Or this uprobe can be filtered out.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) if (vma_has_uprobes(vma, vma->vm_start, vma->vm_end))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) clear_bit(MMF_HAS_UPROBES, &mm->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) static int is_trap_at_addr(struct mm_struct *mm, unsigned long vaddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) struct page *page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) uprobe_opcode_t opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) if (WARN_ON_ONCE(!IS_ALIGNED(vaddr, UPROBE_SWBP_INSN_SIZE)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) pagefault_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) result = __get_user(opcode, (uprobe_opcode_t __user *)vaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) pagefault_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) if (likely(result == 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) * The NULL 'tsk' here ensures that any faults that occur here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) * will not be accounted to the task. 'mm' *is* current->mm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) * but we treat this as a 'remote' access since it is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) * essentially a kernel access to the memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) result = get_user_pages_remote(mm, vaddr, 1, FOLL_FORCE, &page,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) if (result < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) copy_from_page(page, vaddr, &opcode, UPROBE_SWBP_INSN_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) put_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) /* This needs to return true for any variant of the trap insn */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) return is_trap_insn(&opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) static struct uprobe *find_active_uprobe(unsigned long bp_vaddr, int *is_swbp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) struct mm_struct *mm = current->mm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) struct uprobe *uprobe = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) struct vm_area_struct *vma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) mmap_read_lock(mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) vma = find_vma(mm, bp_vaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) if (vma && vma->vm_start <= bp_vaddr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) if (valid_vma(vma, false)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) struct inode *inode = file_inode(vma->vm_file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) loff_t offset = vaddr_to_offset(vma, bp_vaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) uprobe = find_uprobe(inode, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) if (!uprobe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) *is_swbp = is_trap_at_addr(mm, bp_vaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) *is_swbp = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) if (!uprobe && test_and_clear_bit(MMF_RECALC_UPROBES, &mm->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) mmf_recalc_uprobes(mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) mmap_read_unlock(mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) return uprobe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) static void handler_chain(struct uprobe *uprobe, struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) struct uprobe_consumer *uc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) int remove = UPROBE_HANDLER_REMOVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) bool need_prep = false; /* prepare return uprobe, when needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) down_read(&uprobe->register_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) for (uc = uprobe->consumers; uc; uc = uc->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) if (uc->handler) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) rc = uc->handler(uc, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) WARN(rc & ~UPROBE_HANDLER_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) "bad rc=0x%x from %ps()\n", rc, uc->handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) if (uc->ret_handler)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) need_prep = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) remove &= rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) if (need_prep && !remove)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) prepare_uretprobe(uprobe, regs); /* put bp at return */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) if (remove && uprobe->consumers) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) WARN_ON(!uprobe_is_active(uprobe));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) unapply_uprobe(uprobe, current->mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) up_read(&uprobe->register_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) handle_uretprobe_chain(struct return_instance *ri, struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) struct uprobe *uprobe = ri->uprobe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) struct uprobe_consumer *uc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) down_read(&uprobe->register_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) for (uc = uprobe->consumers; uc; uc = uc->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) if (uc->ret_handler)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) uc->ret_handler(uc, ri->func, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) up_read(&uprobe->register_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) static struct return_instance *find_next_ret_chain(struct return_instance *ri)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) bool chained;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) chained = ri->chained;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) ri = ri->next; /* can't be NULL if chained */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) } while (chained);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) return ri;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) static void handle_trampoline(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) struct uprobe_task *utask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) struct return_instance *ri, *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) bool valid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) utask = current->utask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) if (!utask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) goto sigill;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) ri = utask->return_instances;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) if (!ri)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) goto sigill;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) * We should throw out the frames invalidated by longjmp().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) * If this chain is valid, then the next one should be alive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) * or NULL; the latter case means that nobody but ri->func
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) * could hit this trampoline on return. TODO: sigaltstack().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) next = find_next_ret_chain(ri);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) valid = !next || arch_uretprobe_is_alive(next, RP_CHECK_RET, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) instruction_pointer_set(regs, ri->orig_ret_vaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) if (valid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) handle_uretprobe_chain(ri, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) ri = free_ret_instance(ri);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) utask->depth--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) } while (ri != next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) } while (!valid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) utask->return_instances = ri;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) sigill:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) uprobe_warn(current, "handle uretprobe, sending SIGILL.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) force_sig(SIGILL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) bool __weak arch_uprobe_ignore(struct arch_uprobe *aup, struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) bool __weak arch_uretprobe_is_alive(struct return_instance *ret, enum rp_check ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) * Run handler and ask thread to singlestep.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) * Ensure all non-fatal signals cannot interrupt thread while it singlesteps.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) static void handle_swbp(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) struct uprobe *uprobe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) unsigned long bp_vaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) int is_swbp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) bp_vaddr = uprobe_get_swbp_addr(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) if (bp_vaddr == get_trampoline_vaddr())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) return handle_trampoline(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) uprobe = find_active_uprobe(bp_vaddr, &is_swbp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) if (!uprobe) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) if (is_swbp > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) /* No matching uprobe; signal SIGTRAP. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) force_sig(SIGTRAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) * Either we raced with uprobe_unregister() or we can't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) * access this memory. The latter is only possible if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) * another thread plays with our ->mm. In both cases
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) * we can simply restart. If this vma was unmapped we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) * can pretend this insn was not executed yet and get
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) * the (correct) SIGSEGV after restart.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) instruction_pointer_set(regs, bp_vaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) /* change it in advance for ->handler() and restart */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) instruction_pointer_set(regs, bp_vaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) * TODO: move copy_insn/etc into _register and remove this hack.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) * After we hit the bp, _unregister + _register can install the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) * new and not-yet-analyzed uprobe at the same address, restart.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) if (unlikely(!test_bit(UPROBE_COPY_INSN, &uprobe->flags)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) * Pairs with the smp_wmb() in prepare_uprobe().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) * Guarantees that if we see the UPROBE_COPY_INSN bit set, then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) * we must also see the stores to &uprobe->arch performed by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) * prepare_uprobe() call.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) smp_rmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) /* Tracing handlers use ->utask to communicate with fetch methods */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) if (!get_utask())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) if (arch_uprobe_ignore(&uprobe->arch, regs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) handler_chain(uprobe, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) if (arch_uprobe_skip_sstep(&uprobe->arch, regs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) if (!pre_ssout(uprobe, regs, bp_vaddr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) /* arch_uprobe_skip_sstep() succeeded, or restart if can't singlestep */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) put_uprobe(uprobe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) * Perform required fix-ups and disable singlestep.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) * Allow pending signals to take effect.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) static void handle_singlestep(struct uprobe_task *utask, struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) struct uprobe *uprobe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) uprobe = utask->active_uprobe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) if (utask->state == UTASK_SSTEP_ACK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) err = arch_uprobe_post_xol(&uprobe->arch, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) else if (utask->state == UTASK_SSTEP_TRAPPED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) arch_uprobe_abort_xol(&uprobe->arch, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) WARN_ON_ONCE(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) put_uprobe(uprobe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) utask->active_uprobe = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) utask->state = UTASK_RUNNING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) xol_free_insn_slot(current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) spin_lock_irq(¤t->sighand->siglock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) recalc_sigpending(); /* see uprobe_deny_signal() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) spin_unlock_irq(¤t->sighand->siglock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) if (unlikely(err)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) uprobe_warn(current, "execute the probed insn, sending SIGILL.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) force_sig(SIGILL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) * On breakpoint hit, breakpoint notifier sets the TIF_UPROBE flag and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) * allows the thread to return from interrupt. After that handle_swbp()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) * sets utask->active_uprobe.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) * On singlestep exception, singlestep notifier sets the TIF_UPROBE flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) * and allows the thread to return from interrupt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) * While returning to userspace, thread notices the TIF_UPROBE flag and calls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) * uprobe_notify_resume().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) void uprobe_notify_resume(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) struct uprobe_task *utask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) clear_thread_flag(TIF_UPROBE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) utask = current->utask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) if (utask && utask->active_uprobe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) handle_singlestep(utask, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) handle_swbp(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) * uprobe_pre_sstep_notifier gets called from interrupt context as part of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) * notifier mechanism. Set TIF_UPROBE flag and indicate breakpoint hit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) int uprobe_pre_sstep_notifier(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) if (!current->mm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) if (!test_bit(MMF_HAS_UPROBES, ¤t->mm->flags) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) (!current->utask || !current->utask->return_instances))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) set_thread_flag(TIF_UPROBE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) * uprobe_post_sstep_notifier gets called in interrupt context as part of notifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) * mechanism. Set TIF_UPROBE flag and indicate completion of singlestep.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) int uprobe_post_sstep_notifier(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) struct uprobe_task *utask = current->utask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) if (!current->mm || !utask || !utask->active_uprobe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) /* task is currently not uprobed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) utask->state = UTASK_SSTEP_ACK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) set_thread_flag(TIF_UPROBE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) static struct notifier_block uprobe_exception_nb = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) .notifier_call = arch_uprobe_exception_notify,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) .priority = INT_MAX-1, /* notified after kprobes, kgdb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) void __init uprobes_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) for (i = 0; i < UPROBES_HASH_SZ; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) mutex_init(&uprobes_mmap_mutex[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) BUG_ON(register_die_notifier(&uprobe_exception_nb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) }