diff options
author | Peter Zijlstra <peterz@infradead.org> | 2013-05-28 04:55:48 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2013-05-28 05:05:08 -0400 |
commit | 26cb63ad11e04047a64309362674bcbbd6a6f246 (patch) | |
tree | 559c0a9778e7aa6639a24d9a7951879dc65d0551 /include/linux | |
parent | 7b959fc582741227a1c4cba710d6aff8fb183128 (diff) |
perf: Fix perf mmap bugs
Vince reported a problem found by his perf specific trinity
fuzzer.
Al noticed 2 problems with perf's mmap():
- it has issues against fork() since we use vma->vm_mm for accounting.
- it has an rb refcount leak on double mmap().
We fix the issues against fork() by using VM_DONTCOPY; I don't
think there's code out there that uses this; we didn't hear
about weird accounting problems/crashes. If we do need this to
work, the previously proposed VM_PINNED could make this work.
Aside from the rb reference leak spotted by Al, Vince's example
prog was indeed doing a double mmap() through the use of
perf_event_set_output().
This exposes another problem, since we now have 2 events with
one buffer, the accounting gets screwy because we account per
event. Fix this by making the buffer responsible for its own
accounting.
Reported-by: Vince Weaver <vincent.weaver@maine.edu>
Signed-off-by: Peter Zijlstra <peterz@infradead.org>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Link: http://lkml.kernel.org/r/20130528085548.GA12193@twins.programming.kicks-ass.net
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'include/linux')
-rw-r--r-- | include/linux/perf_event.h | 3 |
1 files changed, 1 insertions, 2 deletions
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index f463a46424e2..c5b6dbf9c2fc 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h | |||
@@ -389,8 +389,7 @@ struct perf_event { | |||
389 | /* mmap bits */ | 389 | /* mmap bits */ |
390 | struct mutex mmap_mutex; | 390 | struct mutex mmap_mutex; |
391 | atomic_t mmap_count; | 391 | atomic_t mmap_count; |
392 | int mmap_locked; | 392 | |
393 | struct user_struct *mmap_user; | ||
394 | struct ring_buffer *rb; | 393 | struct ring_buffer *rb; |
395 | struct list_head rb_entry; | 394 | struct list_head rb_entry; |
396 | 395 | ||