mirror of
https://github.com/rd-stuffs/msm-4.14.git
synced 2025-02-20 11:45:48 +08:00
uprobes: Introduce MMF_RECALC_UPROBES
Add the new MMF_RECALC_UPROBES flag, it means that MMF_HAS_UPROBES can be false positive after remove_breakpoint() or uprobe_munmap(). It is also set by uprobe_dup_mmap(), this is not optimal but simple. We could add the new hook, uprobe_dup_vma(), to set MMF_HAS_UPROBES only if the new mm actually has uprobes, but I don't think this makes sense. The next patch will use this flag to clear MMF_HAS_UPROBES. Signed-off-by: Oleg Nesterov <oleg@redhat.com> Acked-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
This commit is contained in:
parent
6f47caa0e1
commit
9f68f672c4
@ -446,7 +446,8 @@ extern int get_dumpable(struct mm_struct *mm);
|
|||||||
#define MMF_VM_HUGEPAGE 17 /* set when VM_HUGEPAGE is set on vma */
|
#define MMF_VM_HUGEPAGE 17 /* set when VM_HUGEPAGE is set on vma */
|
||||||
#define MMF_EXE_FILE_CHANGED 18 /* see prctl_set_mm_exe_file() */
|
#define MMF_EXE_FILE_CHANGED 18 /* see prctl_set_mm_exe_file() */
|
||||||
|
|
||||||
#define MMF_HAS_UPROBES 19 /* might have uprobes */
|
#define MMF_HAS_UPROBES 19 /* has uprobes */
|
||||||
|
#define MMF_RECALC_UPROBES 20 /* MMF_HAS_UPROBES can be wrong */
|
||||||
|
|
||||||
#define MMF_INIT_MASK (MMF_DUMPABLE_MASK | MMF_DUMP_FILTER_MASK)
|
#define MMF_INIT_MASK (MMF_DUMPABLE_MASK | MMF_DUMP_FILTER_MASK)
|
||||||
|
|
||||||
|
@ -684,7 +684,9 @@ install_breakpoint(struct uprobe *uprobe, struct mm_struct *mm,
|
|||||||
set_bit(MMF_HAS_UPROBES, &mm->flags);
|
set_bit(MMF_HAS_UPROBES, &mm->flags);
|
||||||
|
|
||||||
ret = set_swbp(&uprobe->arch, mm, vaddr);
|
ret = set_swbp(&uprobe->arch, mm, vaddr);
|
||||||
if (ret && first_uprobe)
|
if (!ret)
|
||||||
|
clear_bit(MMF_RECALC_UPROBES, &mm->flags);
|
||||||
|
else if (first_uprobe)
|
||||||
clear_bit(MMF_HAS_UPROBES, &mm->flags);
|
clear_bit(MMF_HAS_UPROBES, &mm->flags);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -693,6 +695,11 @@ install_breakpoint(struct uprobe *uprobe, struct mm_struct *mm,
|
|||||||
static void
|
static void
|
||||||
remove_breakpoint(struct uprobe *uprobe, struct mm_struct *mm, unsigned long vaddr)
|
remove_breakpoint(struct uprobe *uprobe, struct mm_struct *mm, unsigned long vaddr)
|
||||||
{
|
{
|
||||||
|
/* can happen if uprobe_register() fails */
|
||||||
|
if (!test_bit(MMF_HAS_UPROBES, &mm->flags))
|
||||||
|
return;
|
||||||
|
|
||||||
|
set_bit(MMF_RECALC_UPROBES, &mm->flags);
|
||||||
set_orig_insn(&uprobe->arch, mm, vaddr);
|
set_orig_insn(&uprobe->arch, mm, vaddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1026,6 +1033,25 @@ int uprobe_mmap(struct vm_area_struct *vma)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
vma_has_uprobes(struct vm_area_struct *vma, unsigned long start, unsigned long end)
|
||||||
|
{
|
||||||
|
loff_t min, max;
|
||||||
|
struct inode *inode;
|
||||||
|
struct rb_node *n;
|
||||||
|
|
||||||
|
inode = vma->vm_file->f_mapping->host;
|
||||||
|
|
||||||
|
min = vaddr_to_offset(vma, start);
|
||||||
|
max = min + (end - start) - 1;
|
||||||
|
|
||||||
|
spin_lock(&uprobes_treelock);
|
||||||
|
n = find_node_in_range(inode, min, max);
|
||||||
|
spin_unlock(&uprobes_treelock);
|
||||||
|
|
||||||
|
return !!n;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Called in context of a munmap of a vma.
|
* Called in context of a munmap of a vma.
|
||||||
*/
|
*/
|
||||||
@ -1037,10 +1063,12 @@ void uprobe_munmap(struct vm_area_struct *vma, unsigned long start, unsigned lon
|
|||||||
if (!atomic_read(&vma->vm_mm->mm_users)) /* called by mmput() ? */
|
if (!atomic_read(&vma->vm_mm->mm_users)) /* called by mmput() ? */
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!test_bit(MMF_HAS_UPROBES, &vma->vm_mm->flags))
|
if (!test_bit(MMF_HAS_UPROBES, &vma->vm_mm->flags) ||
|
||||||
|
test_bit(MMF_RECALC_UPROBES, &vma->vm_mm->flags))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* TODO: unmapping uprobe(s) will need more work */
|
if (vma_has_uprobes(vma, start, end))
|
||||||
|
set_bit(MMF_RECALC_UPROBES, &vma->vm_mm->flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Slot allocation for XOL */
|
/* Slot allocation for XOL */
|
||||||
@ -1146,8 +1174,11 @@ void uprobe_dup_mmap(struct mm_struct *oldmm, struct mm_struct *newmm)
|
|||||||
{
|
{
|
||||||
newmm->uprobes_state.xol_area = NULL;
|
newmm->uprobes_state.xol_area = NULL;
|
||||||
|
|
||||||
if (test_bit(MMF_HAS_UPROBES, &oldmm->flags))
|
if (test_bit(MMF_HAS_UPROBES, &oldmm->flags)) {
|
||||||
set_bit(MMF_HAS_UPROBES, &newmm->flags);
|
set_bit(MMF_HAS_UPROBES, &newmm->flags);
|
||||||
|
/* unconditionally, dup_mmap() skips VM_DONTCOPY vmas */
|
||||||
|
set_bit(MMF_RECALC_UPROBES, &newmm->flags);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user