alpha: perf: fix out-of-bounds array access triggered from raw event
Vince's perf fuzzer uncovered the following issue on Alpha:
Unable to handle kernel paging request at virtual address
fffffbfe4e46a0e8
CPU 0 perf_fuzzer(1278): Oops 0
pc = [<
fffffc000031fbc0>] ra = [<
fffffc000031ff54>] ps = 0007 Not tainted
pc is at alpha_perf_event_set_period+0x60/0xf0
ra is at alpha_pmu_enable+0x1a4/0x1c0
v0 =
0000000000000000 t0 =
00000000000fffff t1 =
fffffc007b3f5800
t2 =
fffffbff275faa94 t3 =
ffffffffc9b9bd89 t4 =
fffffbfe4e46a098
t5 =
0000000000000020 t6 =
fffffbfe4e46a0b8 t7 =
fffffc007f4c8000
s0 =
0000000000000000 s1 =
fffffc0001b0c018 s2 =
fffffc0001b0c020
s3 =
fffffc007b3f5800 s4 =
0000000000000001 s5 =
ffffffffc9b9bd85
s6 =
0000000000000001
a0 =
0000000000000006 a1 =
fffffc007b3f5908 a2 =
fffffbfe4e46a098
a3 =
00000005000108c0 a4 =
0000000000000000 a5 =
0000000000000000
t8 =
0000000000000001 t9 =
0000000000000001 t10=
0000000027829f6f
t11=
0000000000000020 pv =
fffffc000031fb60 at =
fffffc0000950900
gp =
fffffc0000940900 sp =
fffffc007f4cbca8
Disabling lock debugging due to kernel taint
Trace:
[<
fffffc000031ff54>] alpha_pmu_enable+0x1a4/0x1c0
[<
fffffc000039f4e8>] perf_pmu_enable+0x48/0x60
[<
fffffc00003a0d6c>] __perf_install_in_context+0x15c/0x230
[<
fffffc000039d1f0>] remote_function+0x80/0xa0
[<
fffffc00003a0c10>] __perf_install_in_context+0x0/0x230
[<
fffffc000037b7e4>] smp_call_function_single+0x1b4/0x1d0
[<
fffffc000039bb70>] task_function_call+0x60/0x80
[<
fffffc00003a0c10>] __perf_install_in_context+0x0/0x230
[<
fffffc000039bb44>] task_function_call+0x34/0x80
[<
fffffc000039d3fc>] perf_install_in_context+0x9c/0x150
[<
fffffc00003a0c10>] __perf_install_in_context+0x0/0x230
[<
fffffc00003a5100>] SYSC_perf_event_open+0x360/0xac0
[<
fffffc00003110c4>] entSys+0xa4/0xc0
This is due to the raw event encoding being used as an index directly
into the ev67_mapping array, rather than being validated against the
ev67_pmc_event_type enumeration instead. Unlike other architectures,
which allow raw events to propagate into the hardware counters with
little interference, the limited number of events on Alpha and the
strict event <-> counter relationships mean that raw events actually
correspond to the Linux-specific Alpha events, rather than anything
defined by the architecture.
This patch adds a new callback to alpha_pmu_t for validating the raw
event encoding with the Linux event types for the PMU, preventing the
out-of-bounds array access.
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Acked-by: Michael Cree <mcree@orcon.net.nz>
Acked-by: Matt Turner <mattst88@gmail.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>