diff options
author | Oleg Nesterov <oleg@redhat.com> | 2011-01-18 11:10:32 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2011-01-18 13:34:23 -0500 |
commit | 66832eb4baaaa9abe4c993ddf9113a79e39b9915 (patch) | |
tree | bc1b60069c5313231a5ddca0f0dcab953489bb1e | |
parent | 22a4ec729017ba613337a28f306f94ba5023fe2e (diff) |
perf: Validate cpu early in perf_event_alloc()
Starting from perf_event_alloc()->perf_init_event(), the kernel
assumes that event->cpu is either -1 or the valid CPU number.
Change perf_event_alloc() to validate this argument early. This
also means we can remove the similar check in
find_get_context().
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Prasad <prasad@linux.vnet.ibm.com>
Cc: Roland McGrath <roland@redhat.com>
Cc: gregkh@suse.de
Cc: stable@kernel.org
LKML-Reference: <20110118161032.GC693@redhat.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r-- | kernel/perf_event.c | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/kernel/perf_event.c b/kernel/perf_event.c index a962b1962eee..67d9bd70b746 100644 --- a/kernel/perf_event.c +++ b/kernel/perf_event.c | |||
@@ -2233,9 +2233,6 @@ find_get_context(struct pmu *pmu, struct task_struct *task, int cpu) | |||
2233 | if (perf_paranoid_cpu() && !capable(CAP_SYS_ADMIN)) | 2233 | if (perf_paranoid_cpu() && !capable(CAP_SYS_ADMIN)) |
2234 | return ERR_PTR(-EACCES); | 2234 | return ERR_PTR(-EACCES); |
2235 | 2235 | ||
2236 | if (cpu < 0 || cpu >= nr_cpumask_bits) | ||
2237 | return ERR_PTR(-EINVAL); | ||
2238 | |||
2239 | /* | 2236 | /* |
2240 | * We could be clever and allow to attach a event to an | 2237 | * We could be clever and allow to attach a event to an |
2241 | * offline CPU and activate it when the CPU comes up, but | 2238 | * offline CPU and activate it when the CPU comes up, but |
@@ -5541,6 +5538,11 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu, | |||
5541 | struct hw_perf_event *hwc; | 5538 | struct hw_perf_event *hwc; |
5542 | long err; | 5539 | long err; |
5543 | 5540 | ||
5541 | if ((unsigned)cpu >= nr_cpu_ids) { | ||
5542 | if (!task || cpu != -1) | ||
5543 | return ERR_PTR(-EINVAL); | ||
5544 | } | ||
5545 | |||
5544 | event = kzalloc(sizeof(*event), GFP_KERNEL); | 5546 | event = kzalloc(sizeof(*event), GFP_KERNEL); |
5545 | if (!event) | 5547 | if (!event) |
5546 | return ERR_PTR(-ENOMEM); | 5548 | return ERR_PTR(-ENOMEM); |
@@ -5589,7 +5591,7 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu, | |||
5589 | 5591 | ||
5590 | if (!overflow_handler && parent_event) | 5592 | if (!overflow_handler && parent_event) |
5591 | overflow_handler = parent_event->overflow_handler; | 5593 | overflow_handler = parent_event->overflow_handler; |
5592 | 5594 | ||
5593 | event->overflow_handler = overflow_handler; | 5595 | event->overflow_handler = overflow_handler; |
5594 | 5596 | ||
5595 | if (attr->disabled) | 5597 | if (attr->disabled) |