diff options
author | Peter Zijlstra <peterz@infradead.org> | 2018-04-20 08:23:36 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2018-05-05 02:37:29 -0400 |
commit | 06ce6e9b6d6c09d4129c6e24a1314a395d816c10 (patch) | |
tree | 3b7e42aa15470dccdf7ec2463ace66f814440eaa | |
parent | 46b1b577229a091b137831becaa0fae8690ee15a (diff) |
perf/x86/msr: Fix possible Spectre-v1 indexing in the MSR driver
> arch/x86/events/msr.c:178 msr_event_init() warn: potential spectre issue 'msr' (local cap)
Userspace controls @attr, sanitize cfg (attr->config) before using it
to index an array.
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: <stable@kernel.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Vince Weaver <vincent.weaver@maine.edu>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r-- | arch/x86/events/msr.c | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/arch/x86/events/msr.c b/arch/x86/events/msr.c index e7edf19e64c2..b4771a6ddbc1 100644 --- a/arch/x86/events/msr.c +++ b/arch/x86/events/msr.c | |||
@@ -1,5 +1,6 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
2 | #include <linux/perf_event.h> | 2 | #include <linux/perf_event.h> |
3 | #include <linux/nospec.h> | ||
3 | #include <asm/intel-family.h> | 4 | #include <asm/intel-family.h> |
4 | 5 | ||
5 | enum perf_msr_id { | 6 | enum perf_msr_id { |
@@ -158,9 +159,6 @@ static int msr_event_init(struct perf_event *event) | |||
158 | if (event->attr.type != event->pmu->type) | 159 | if (event->attr.type != event->pmu->type) |
159 | return -ENOENT; | 160 | return -ENOENT; |
160 | 161 | ||
161 | if (cfg >= PERF_MSR_EVENT_MAX) | ||
162 | return -EINVAL; | ||
163 | |||
164 | /* unsupported modes and filters */ | 162 | /* unsupported modes and filters */ |
165 | if (event->attr.exclude_user || | 163 | if (event->attr.exclude_user || |
166 | event->attr.exclude_kernel || | 164 | event->attr.exclude_kernel || |
@@ -171,6 +169,11 @@ static int msr_event_init(struct perf_event *event) | |||
171 | event->attr.sample_period) /* no sampling */ | 169 | event->attr.sample_period) /* no sampling */ |
172 | return -EINVAL; | 170 | return -EINVAL; |
173 | 171 | ||
172 | if (cfg >= PERF_MSR_EVENT_MAX) | ||
173 | return -EINVAL; | ||
174 | |||
175 | cfg = array_index_nospec((unsigned long)cfg, PERF_MSR_EVENT_MAX); | ||
176 | |||
174 | if (!msr[cfg].attr) | 177 | if (!msr[cfg].attr) |
175 | return -EINVAL; | 178 | return -EINVAL; |
176 | 179 | ||