[linux] 02/09: [arm64] perf: reject groups spanning multiple HW PMUs (CVE-2015-8955)

debian-kernel at lists.debian.org debian-kernel at lists.debian.org
Thu Dec 1 00:23:47 UTC 2016


This is an automated email from the git hooks/post-receive script.

benh pushed a commit to branch jessie-security
in repository linux.

commit 76cee5fc8a407b659458cfcd371a791dd3e5d934
Author: Ben Hutchings <ben at decadent.org.uk>
Date:   Wed Nov 30 20:24:47 2016 +0000

    [arm64] perf: reject groups spanning multiple HW PMUs (CVE-2015-8955)
---
 debian/changelog                                   |   1 +
 ...f-reject-groups-spanning-multiple-hw-pmus.patch | 109 +++++++++++++++++++++
 debian/patches/series                              |   1 +
 3 files changed, 111 insertions(+)

diff --git a/debian/changelog b/debian/changelog
index b01b3c2..24b50c6 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -5,6 +5,7 @@ linux (3.16.36-1+deb8u3) UNRELEASED; urgency=medium
   * fs: Give dentry to inode_change_ok() instead of inode
   * fs: Avoid premature clearing of capabilities (CVE-2015-1350)
     (Closes: #770492)
+  * [arm64] perf: reject groups spanning multiple HW PMUs (CVE-2015-8955)
 
  -- Ben Hutchings <ben at decadent.org.uk>  Wed, 30 Nov 2016 04:06:41 +0000
 
diff --git a/debian/patches/bugfix/arm64/arm64-perf-reject-groups-spanning-multiple-hw-pmus.patch b/debian/patches/bugfix/arm64/arm64-perf-reject-groups-spanning-multiple-hw-pmus.patch
new file mode 100644
index 0000000..7e6d293
--- /dev/null
+++ b/debian/patches/bugfix/arm64/arm64-perf-reject-groups-spanning-multiple-hw-pmus.patch
@@ -0,0 +1,109 @@
+From: "Suzuki K. Poulose" <suzuki.poulose at arm.com>
+Date: Tue, 17 Mar 2015 18:14:59 +0000
+Subject: arm64: perf: reject groups spanning multiple HW PMUs
+Origin: https://git.kernel.org/linus/8fff105e13041e49b82f92eef034f363a6b1c071
+
+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 : [<ffffffc000090228>] pstate: 00000145
+sp : ffffffc07b0a3ba0
+
+[<          (null)>]           (null)
+[<ffffffc0000907d8>] armpmu_event_init+0x174/0x3cc
+[<ffffffc00015d870>] perf_try_init_event+0x34/0x70
+[<ffffffc000164094>] perf_init_event+0xe0/0x10c
+[<ffffffc000164348>] perf_event_alloc+0x288/0x358
+[<ffffffc000164c5c>] 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 <will.deacon at arm.com>
+Acked-by: Mark Rutland <mark.rutland at arm.com>
+Acked-by: Peter Ziljstra (Intel) <peterz at infradead.org>
+Signed-off-by: Suzuki K. Poulose <suzuki.poulose at arm.com>
+Signed-off-by: Will Deacon <will.deacon at arm.com>
+Signed-off-by: Ben Hutchings <ben at decadent.org.uk>
+---
+ arch/arm64/kernel/perf_event.c | 21 +++++++++++++++------
+ 1 file changed, 15 insertions(+), 6 deletions(-)
+
+diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
+index 6166745ecb93..be0ff66e4894 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;
diff --git a/debian/patches/series b/debian/patches/series
index a0e2e92..16fdf50 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -686,6 +686,7 @@ bugfix/all/xfs-propagate-dentry-down-to-inode_change_ok.patch
 bugfix/all/fuse-propagate-dentry-down-to-inode_change_ok.patch
 bugfix/all/fs-give-dentry-to-inode_change_ok-instead-of-inode.patch
 bugfix/all/fs-avoid-premature-clearing-of-capabilities.patch
+bugfix/arm64/arm64-perf-reject-groups-spanning-multiple-hw-pmus.patch
 
 # Fix ABI changes
 debian/of-fix-abi-changes.patch

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/kernel/linux.git



More information about the Kernel-svn-changes mailing list