Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751351Ab3IJK3I (ORCPT ); Tue, 10 Sep 2013 06:29:08 -0400 Received: from nctlincom02.orcon.net.nz ([60.234.4.76]:39370 "EHLO nctlincom02.orcon.net.nz" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751216Ab3IJK3H (ORCPT ); Tue, 10 Sep 2013 06:29:07 -0400 X-Greylist: delayed 552 seconds by postgrey-1.27 at vger.kernel.org; Tue, 10 Sep 2013 06:29:07 EDT Date: Tue, 10 Sep 2013 22:19:44 +1200 From: Michael Cree To: Will Deacon Cc: linux-alpha@vger.kernel.org, linux-kernel@vger.kernel.org, Peter Zijlstra , Matt Turner Subject: Re: [PATCH] alpha: perf: fix out-of-bounds array access triggered from raw event Message-ID: <20130910101944.GA13664@omega> Mail-Followup-To: Michael Cree , Will Deacon , linux-alpha@vger.kernel.org, linux-kernel@vger.kernel.org, Peter Zijlstra , Matt Turner References: <1378807092-28674-1-git-send-email-will.deacon@arm.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1378807092-28674-1-git-send-email-will.deacon@arm.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-DSPAM-Check: by mx9.orcon.net.nz on Tue, 10 Sep 2013 22:19:51 +1200 X-DSPAM-Result: Innocent X-DSPAM-Processed: Tue Sep 10 22:19:51 2013 X-DSPAM-Confidence: 0.9944 X-DSPAM-Probability: 0.0000 X-Bayes-Prob: 0.0001 (Score 0, tokens from: @@RPTN, default) X-Spam-Score: -3.00 () [Hold at 4.00] CC(NZ:-3) X-CanIt-Geo: ip=60.234.221.162; country=NZ; region=E7; city=Auckland; latitude=-36.8667; longitude=174.7667; http://maps.google.com/maps?q=-36.8667,174.7667&z=6 X-CanItPRO-Stream: base:default X-Canit-Stats-ID: 05KnmjPqk - 20860be48ce4 - 20130910 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 4793 Lines: 118 On Tue, Sep 10, 2013 at 10:58:12AM +0100, Will Deacon wrote: > 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 = [] ra = [] 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: > [] alpha_pmu_enable+0x1a4/0x1c0 > [] perf_pmu_enable+0x48/0x60 > [] __perf_install_in_context+0x15c/0x230 > [] remote_function+0x80/0xa0 > [] __perf_install_in_context+0x0/0x230 > [] smp_call_function_single+0x1b4/0x1d0 > [] task_function_call+0x60/0x80 > [] __perf_install_in_context+0x0/0x230 > [] task_function_call+0x34/0x80 > [] perf_install_in_context+0x9c/0x150 > [] __perf_install_in_context+0x0/0x230 > [] SYSC_perf_event_open+0x360/0xac0 > [] 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 > Cc: Michael Cree > Cc: Matt Turner > Signed-off-by: Will Deacon Acked-by: Michael Cree Cheers Michael. > --- > arch/alpha/kernel/perf_event.c | 15 +++++++++++++-- > 1 file changed, 13 insertions(+), 2 deletions(-) > > diff --git a/arch/alpha/kernel/perf_event.c b/arch/alpha/kernel/perf_event.c > index d821b17..c52e7f0 100644 > --- a/arch/alpha/kernel/perf_event.c > +++ b/arch/alpha/kernel/perf_event.c > @@ -83,6 +83,8 @@ struct alpha_pmu_t { > long pmc_left[3]; > /* Subroutine for allocation of PMCs. Enforces constraints. */ > int (*check_constraints)(struct perf_event **, unsigned long *, int); > + /* Subroutine for checking validity of a raw event for this PMU. */ > + int (*raw_event_valid)(u64 config); > }; > > /* > @@ -203,6 +205,12 @@ success: > } > > > +static int ev67_raw_event_valid(u64 config) > +{ > + return config >= EV67_CYCLES && config < EV67_LAST_ET; > +}; > + > + > static const struct alpha_pmu_t ev67_pmu = { > .event_map = ev67_perfmon_event_map, > .max_events = ARRAY_SIZE(ev67_perfmon_event_map), > @@ -211,7 +219,8 @@ static const struct alpha_pmu_t ev67_pmu = { > .pmc_count_mask = {EV67_PCTR_0_COUNT_MASK, EV67_PCTR_1_COUNT_MASK, 0}, > .pmc_max_period = {(1UL<<20) - 1, (1UL<<20) - 1, 0}, > .pmc_left = {16, 4, 0}, > - .check_constraints = ev67_check_constraints > + .check_constraints = ev67_check_constraints, > + .raw_event_valid = ev67_raw_event_valid, > }; > > > @@ -609,7 +618,9 @@ static int __hw_perf_event_init(struct perf_event *event) > } else if (attr->type == PERF_TYPE_HW_CACHE) { > return -EOPNOTSUPP; > } else if (attr->type == PERF_TYPE_RAW) { > - ev = attr->config & 0xff; > + if (!alpha_pmu->raw_event_valid(attr->config)) > + return -EINVAL; > + ev = attr->config; > } else { > return -EOPNOTSUPP; > } > -- > 1.8.3.2 > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/