| From: Pekka Enberg <penberg@kernel.org> |
| Date: Mon, 8 Nov 2010 19:29:07 +0000 (+0200) |
| Subject: perf_events: Fix perf_counter_mmap() hook in mprotect() |
| X-Git-Tag: v2.6.37-rc2~72 |
| X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=63bfd7384b119409685a17d5c58f0b56e5dc03da |
| |
| perf_events: Fix perf_counter_mmap() hook in mprotect() |
| |
| As pointed out by Linus, commit dab5855 ("perf_counter: Add mmap event hooks to |
| mprotect()") is fundamentally wrong as mprotect_fixup() can free 'vma' due to |
| merging. Fix the problem by moving perf_event_mmap() hook to |
| mprotect_fixup(). |
| |
| Note: there's another successful return path from mprotect_fixup() if old |
| flags equal to new flags. We don't, however, need to call |
| perf_event_mmap() there because 'perf' already knows the VMA is |
| executable. |
| |
| Reported-by: Dave Jones <davej@redhat.com> |
| Analyzed-by: Linus Torvalds <torvalds@linux-foundation.org> |
| Cc: Ingo Molnar <mingo@elte.hu> |
| Reviewed-by: Peter Zijlstra <a.p.zijlstra@chello.nl> |
| Signed-off-by: Pekka Enberg <penberg@kernel.org> |
| Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> |
| |
| |
| diff --git a/mm/mprotect.c b/mm/mprotect.c |
| index 2d1bf7c..4c51338 100644 |
| |
| |
| @@ -211,6 +211,7 @@ success: |
| mmu_notifier_invalidate_range_end(mm, start, end); |
| vm_stat_account(mm, oldflags, vma->vm_file, -nrpages); |
| vm_stat_account(mm, newflags, vma->vm_file, nrpages); |
| + perf_event_mmap(vma); |
| return 0; |
| |
| fail: |
| @@ -299,7 +300,6 @@ SYSCALL_DEFINE3(mprotect, unsigned long, start, size_t, len, |
| error = mprotect_fixup(vma, &prev, nstart, tmp, newflags); |
| if (error) |
| goto out; |
| - perf_event_mmap(vma); |
| nstart = tmp; |
| |
| if (nstart < prev->vm_end) |