From patchwork Tue May 9 14:42:27 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amit Pundir X-Patchwork-Id: 98916 Delivered-To: patch@linaro.org Received: by 10.140.96.100 with SMTP id j91csp1857342qge; Tue, 9 May 2017 07:43:02 -0700 (PDT) X-Received: by 10.98.22.9 with SMTP id 9mr236450pfw.125.1494340982363; Tue, 09 May 2017 07:43:02 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1494340982; cv=none; d=google.com; s=arc-20160816; b=QYjVeaw5ZiuU8+jCcka4/4ImLcn6m/w1bE7AGkooIxPG8ATt1Z06SuoGW2PyF8WmEG KVKPJ/BUtd5O5zqJ5lmjyEFhMuvm0lqRf7l6q+8l71J2iH5Bsi6v3i28mNn30B2QLSvu NaRmFnnefTxNEnclukh43mbW9ye9AmecliJkYA+25PbLfefJN6smTrLeJNav8C1R14L4 ZUM65btAlLwJkAHv/KKZVFXlyjnG5ObHhxWTXi7GUxI9BXzM9p3vb6juGdGpxDaAc8sB yu5OIgfEVQQvwL6N62CvMzwotJDRHJVVbE2KbSE7eSj6PT3BGdvSON3BRu4/1tXPC5uL ah7w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=vVSWcxe0RJnoub4iUkiKKDAl07/Sshs7ZkTcJ2r/hfo=; b=PUGoJg0RxYigidmcPBZs14c8OVsuW7cdNwCwH4ICMgFp3Qcn1Wtru2dwp23jzMINuN xV770ENG26BMkOBrnXeb2XB+j+o+t5yvxNaRCpRi0yDf7dV4s5LfJimEpTfiNu6IUIpR /IxxhYToVEAyAp5zWl7W/Ptg84F2TnVDDN3J4ELCt+hqc7C7uFcdG9qdXLrVPlCTpG3B bD5xThlW+B0elaUmDhXrniY3KgklYDEzr9LL1QAs/qanHGjbA1jzTqAruI7pBF/aUWPR Yk0aAgJ2TEV/5RuPKDvL4Ik8k1B383e+JjIxI2L9wkoxXm9UNqUP80AwE81gBcMQMgWU 3yRQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org; spf=pass (google.com: best guess record for domain of stable-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=stable-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id w34si113540pla.121.2017.05.09.07.43.02; Tue, 09 May 2017 07:43:02 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of stable-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org; spf=pass (google.com: best guess record for domain of stable-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=stable-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751306AbdEIOnB (ORCPT + 6 others); Tue, 9 May 2017 10:43:01 -0400 Received: from mail-pf0-f181.google.com ([209.85.192.181]:36052 "EHLO mail-pf0-f181.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751210AbdEIOnA (ORCPT ); Tue, 9 May 2017 10:43:00 -0400 Received: by mail-pf0-f181.google.com with SMTP id m17so1140524pfg.3 for ; Tue, 09 May 2017 07:43:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=vVSWcxe0RJnoub4iUkiKKDAl07/Sshs7ZkTcJ2r/hfo=; b=ic06Xvyn+unQsvgQ7171UPzySgBNqlkGbO3mwTJx2DRXQ4WExbp++2eVO15+Zqv30B W/IXW40mu836MsiMFcKgZ4Glkgyk6nIL7YwKDuSl5xLxh9zqaXM63+ASxY6RWIh/eKeF hiOd6VuiPVQuc5lG6RMCmouisuXrH2SoCJNws= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=vVSWcxe0RJnoub4iUkiKKDAl07/Sshs7ZkTcJ2r/hfo=; b=WZpa8Gy2pfXN+JSW91MxhCQHYaTdHAfJrL2uMwi9l3TPzzB/AmbnJcQT8PgF5pRT6G si+WTbsSc9v0CuZjhXXfXEIUj/BUkpgt5GDj+jKz8QF6TwfaY28xLK2UOR2JeTFQBd0I KHdO3yzf/X1+JvBNsuXa4Li2TLUPoLOIoZvgB/ZiuhEfBFxP/D1XPmaLs8VZLtmMGnQp e2S7TgohaMD7+mFGbSbyyZHw5WEW8kXYfVmLut57HWQOsq4QuM53VYNsVer3BZRkxy9g K7Nt8Iyhrids+ooXnUTITlPzT+mU2I4FIQsha9fPuIJ5Yzp1Ry94vgjzdRg0YlAkUdl2 Yvyw== X-Gm-Message-State: AODbwcDO+h2FyNvRinVr8WFpzaoj+hxwFIJzcmEFc4IK9rRAqbVi5p9S bRxOPZNEdvO7kwFX X-Received: by 10.84.217.201 with SMTP id d9mr666934plj.164.1494340980053; Tue, 09 May 2017 07:43:00 -0700 (PDT) Received: from localhost.localdomain ([106.51.135.126]) by smtp.gmail.com with ESMTPSA id 11sm341811pfj.59.2017.05.09.07.42.58 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 09 May 2017 07:42:59 -0700 (PDT) From: Amit Pundir To: Greg KH Cc: stable@vger.kernel.org, "Suzuki K. Poulose" , Will Deacon Subject: [PATCH for-3.18 03/24] arm64: perf: reject groups spanning multiple HW PMUs Date: Tue, 9 May 2017 20:12:27 +0530 Message-Id: <1494340968-17152-4-git-send-email-amit.pundir@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1494340968-17152-1-git-send-email-amit.pundir@linaro.org> References: <1494340968-17152-1-git-send-email-amit.pundir@linaro.org> Sender: stable-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: stable@vger.kernel.org From: "Suzuki K. Poulose" commit 8fff105e13041e49b82f92eef034f363a6b1c071 upstream. The perf core implicitly rejects events spanning multiple HW PMUs, as in these cases the event->ctx will differ. However this validation is performed after pmu::event_init() is called in perf_init_event(), and thus pmu::event_init() may be called with a group leader from a different HW PMU. The ARM64 PMU driver does not take this fact into account, and when validating groups assumes that it can call to_arm_pmu(event->pmu) for any HW event. When the event in question is from another HW PMU this is wrong, and results in dereferencing garbage. This patch updates the ARM64 PMU driver to first test for and reject events from other PMUs, moving the to_arm_pmu and related logic after this test. Fixes a crash triggered by perf_fuzzer on Linux-4.0-rc2, with a CCI PMU present: Bad mode in Synchronous Abort handler detected, code 0x86000006 -- IABT (current EL) CPU: 0 PID: 1371 Comm: perf_fuzzer Not tainted 3.19.0+ #249 Hardware name: V2F-1XV7 Cortex-A53x2 SMM (DT) task: ffffffc07c73a280 ti: ffffffc07b0a0000 task.ti: ffffffc07b0a0000 PC is at 0x0 LR is at validate_event+0x90/0xa8 pc : [<0000000000000000>] lr : [] pstate: 00000145 sp : ffffffc07b0a3ba0 [< (null)>] (null) [] armpmu_event_init+0x174/0x3cc [] perf_try_init_event+0x34/0x70 [] perf_init_event+0xe0/0x10c [] perf_event_alloc+0x288/0x358 [] SyS_perf_event_open+0x464/0x98c Code: bad PC value Also cleans up the code to use the arm_pmu only when we know that we are dealing with an arm pmu event. Cc: Will Deacon Acked-by: Mark Rutland Acked-by: Peter Ziljstra (Intel) Signed-off-by: Suzuki K. Poulose Signed-off-by: Will Deacon Signed-off-by: Amit Pundir --- arch/arm64/kernel/perf_event.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) -- 2.7.4 diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c index aa29ecb4f800..78a5894b1621 100644 --- a/arch/arm64/kernel/perf_event.c +++ b/arch/arm64/kernel/perf_event.c @@ -316,22 +316,31 @@ out: } static int -validate_event(struct pmu_hw_events *hw_events, - struct perf_event *event) +validate_event(struct pmu *pmu, struct pmu_hw_events *hw_events, + struct perf_event *event) { - struct arm_pmu *armpmu = to_arm_pmu(event->pmu); + struct arm_pmu *armpmu; struct hw_perf_event fake_event = event->hw; struct pmu *leader_pmu = event->group_leader->pmu; if (is_software_event(event)) return 1; + /* + * Reject groups spanning multiple HW PMUs (e.g. CPU + CCI). The + * core perf code won't check that the pmu->ctx == leader->ctx + * until after pmu->event_init(event). + */ + if (event->pmu != pmu) + return 0; + if (event->pmu != leader_pmu || event->state < PERF_EVENT_STATE_OFF) return 1; if (event->state == PERF_EVENT_STATE_OFF && !event->attr.enable_on_exec) return 1; + armpmu = to_arm_pmu(event->pmu); return armpmu->get_event_idx(hw_events, &fake_event) >= 0; } @@ -349,15 +358,15 @@ validate_group(struct perf_event *event) memset(fake_used_mask, 0, sizeof(fake_used_mask)); fake_pmu.used_mask = fake_used_mask; - if (!validate_event(&fake_pmu, leader)) + if (!validate_event(event->pmu, &fake_pmu, leader)) return -EINVAL; list_for_each_entry(sibling, &leader->sibling_list, group_entry) { - if (!validate_event(&fake_pmu, sibling)) + if (!validate_event(event->pmu, &fake_pmu, sibling)) return -EINVAL; } - if (!validate_event(&fake_pmu, event)) + if (!validate_event(event->pmu, &fake_pmu, event)) return -EINVAL; return 0;