diff options
author | Oleg Nesterov <oleg@redhat.com> | 2012-07-29 14:22:12 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2012-07-30 05:27:18 -0400 |
commit | f403072c6108e15f319a4a5036b650c77760522c (patch) | |
tree | 196781f30871635b7c8fc702a7566b5ed09e525c /kernel | |
parent | 35d56ca9d401d9d0ac8d91e4db1485af5f38f6fd (diff) |
uprobes: Don't recheck vma/f_mapping in write_opcode()
write_opcode() rechecks valid_vma() and ->f_mapping, this is
pointless. The caller, register_for_each_vma() or uprobe_mmap(),
has already done these checks under mmap_sem.
To clarify, uprobe_mmap() checks valid_vma() only, but we can
rely on build_probe_list(vm_file->f_mapping->host).
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Acked-by: Srikar Dronamraju <srikar.vnet.ibm.com>
Cc: Anton Arapov <anton@redhat.com>
Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
Link: http://lkml.kernel.org/r/20120729182212.GA20304@redhat.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/events/uprobes.c | 19 |
1 files changed, 1 insertions, 18 deletions
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index f93532748bca..a2b32a51d0a2 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c | |||
@@ -206,33 +206,16 @@ static int write_opcode(struct arch_uprobe *auprobe, struct mm_struct *mm, | |||
206 | unsigned long vaddr, uprobe_opcode_t opcode) | 206 | unsigned long vaddr, uprobe_opcode_t opcode) |
207 | { | 207 | { |
208 | struct page *old_page, *new_page; | 208 | struct page *old_page, *new_page; |
209 | struct address_space *mapping; | ||
210 | void *vaddr_old, *vaddr_new; | 209 | void *vaddr_old, *vaddr_new; |
211 | struct vm_area_struct *vma; | 210 | struct vm_area_struct *vma; |
212 | struct uprobe *uprobe; | ||
213 | int ret; | 211 | int ret; |
212 | |||
214 | retry: | 213 | retry: |
215 | /* Read the page with vaddr into memory */ | 214 | /* Read the page with vaddr into memory */ |
216 | ret = get_user_pages(NULL, mm, vaddr, 1, 0, 0, &old_page, &vma); | 215 | ret = get_user_pages(NULL, mm, vaddr, 1, 0, 0, &old_page, &vma); |
217 | if (ret <= 0) | 216 | if (ret <= 0) |
218 | return ret; | 217 | return ret; |
219 | 218 | ||
220 | ret = -EINVAL; | ||
221 | |||
222 | /* | ||
223 | * We are interested in text pages only. Our pages of interest | ||
224 | * should be mapped for read and execute only. We desist from | ||
225 | * adding probes in write mapped pages since the breakpoints | ||
226 | * might end up in the file copy. | ||
227 | */ | ||
228 | if (!valid_vma(vma, is_swbp_insn(&opcode))) | ||
229 | goto put_out; | ||
230 | |||
231 | uprobe = container_of(auprobe, struct uprobe, arch); | ||
232 | mapping = uprobe->inode->i_mapping; | ||
233 | if (mapping != vma->vm_file->f_mapping) | ||
234 | goto put_out; | ||
235 | |||
236 | ret = -ENOMEM; | 219 | ret = -ENOMEM; |
237 | new_page = alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma, vaddr); | 220 | new_page = alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma, vaddr); |
238 | if (!new_page) | 221 | if (!new_page) |