lkml.org 
[lkml]   [2012]   [Apr]   [5]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[PATCH 4/6] uprobes: change register_for_each_vma() to take mm->mmap_sem for writing
Change register_for_each_vma() to take mm->mmap_sem for writing.
This is a bit unfortunate but hopefully not too bad, this is the
slow path anyway.

This is needed to ensure that find_active_uprobe() can not race
with uprobe_register() which adds the new bp at the same bp_vaddr,
after find_uprobe() fails and before is_swbp_at_addr_fast() checks
the memory.

IOW, this is needed to ensure that if find_active_uprobe() returns
NULL but is_swbp == true, we can safely assume that it was the
"normal" int3 and we should send SIGTRAP.
---
kernel/events/uprobes.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
index 054c00f..2af458d 100644
--- a/kernel/events/uprobes.c
+++ b/kernel/events/uprobes.c
@@ -838,12 +838,12 @@ static int register_for_each_vma(struct uprobe *uprobe, bool is_register)
}

mm = vi->mm;
- down_read(&mm->mmap_sem);
+ down_write(&mm->mmap_sem);
vma = find_vma(mm, (unsigned long)vi->vaddr);
if (!vma || !valid_vma(vma, is_register)) {
list_del(&vi->probe_list);
kfree(vi);
- up_read(&mm->mmap_sem);
+ up_write(&mm->mmap_sem);
mmput(mm);
continue;
}
@@ -852,7 +852,7 @@ static int register_for_each_vma(struct uprobe *uprobe, bool is_register)
vaddr != vi->vaddr) {
list_del(&vi->probe_list);
kfree(vi);
- up_read(&mm->mmap_sem);
+ up_write(&mm->mmap_sem);
mmput(mm);
continue;
}
@@ -862,7 +862,7 @@ static int register_for_each_vma(struct uprobe *uprobe, bool is_register)
else
remove_breakpoint(uprobe, mm, vi->vaddr);

- up_read(&mm->mmap_sem);
+ up_write(&mm->mmap_sem);
mmput(mm);
if (is_register) {
if (ret && ret == -EEXIST)
--
1.5.5.1



\
 
 \ /
  Last update: 2012-04-06 00:25    [from the cache]
©2003-2011 Jasper Spaans