DivestOS/Patches/Linux_CVEs/CVE-2016-3768/ANY/0001.patch

91 lines
3.3 KiB
Diff
Raw Normal View History

2017-11-07 17:32:46 -05:00
From d75be03af111fb5a31eba82f665242e6d8b07008 Mon Sep 17 00:00:00 2001
From: Arun KS <arunks@codeaurora.org>
Date: Wed, 11 May 2016 10:11:36 +0530
Subject: msm: perf: Do not allocate new hw_event if event is duplicate.
During a perf_event_enable, kernel/events/core.c calls pmu->add() which
is platform implementation(arch/arm/kernel/perf_event.c). Due to the
duplicate constraints, arch/arm/mach-msm/perf_event_msm_krait_l2.c
drivers marks the event as OFF but returns TRUE to perf_event.c which
goes ahead and allocates the hw_event and enables it.
2017-11-07 17:32:46 -05:00
Since event is marked OFF, kernel events core will try to enable this event
again during next perf_event_enable. Which results in same event enabled
on multiple hw_events. But during the perf_release, event struct is freed
and only one hw_event is released. This results in dereferencing the
invalid pointer and hence the crash.
2017-11-07 17:32:46 -05:00
Fix this by returning error in case of constraint event duplicate. Hence
avoiding the same event programmed on multiple hw event counters.
Change-Id: Ia3360be027dfe87ac753191ffe7e0bc947e72455
Signed-off-by: Arun KS <arunks@codeaurora.org>
---
arch/arm/kernel/perf_event.c | 1 +
arch/arm/mach-msm/perf_event_msm_krait_l2.c | 1 +
2017-11-07 17:32:46 -05:00
arch/arm/mach-msm/perf_event_msm_l2.c | 4 +++-
kernel/events/core.c | 7 -------
4 files changed, 5 insertions(+), 8 deletions(-)
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
2017-11-07 17:32:46 -05:00
index 1541a80..a1264ac 100644
--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
2017-11-07 17:32:46 -05:00
@@ -308,6 +308,7 @@ armpmu_add(struct perf_event *event, int flags)
pr_err("Event: %llx failed constraint check.\n",
event->attr.config);
event->state = PERF_EVENT_STATE_OFF;
+ err = -EPERM;
goto out;
}
diff --git a/arch/arm/mach-msm/perf_event_msm_krait_l2.c b/arch/arm/mach-msm/perf_event_msm_krait_l2.c
2017-11-07 17:32:46 -05:00
index d816794..57f82d0 100644
--- a/arch/arm/mach-msm/perf_event_msm_krait_l2.c
+++ b/arch/arm/mach-msm/perf_event_msm_krait_l2.c
2017-11-07 17:32:46 -05:00
@@ -463,6 +463,7 @@ static int msm_l2_test_set_ev_constraint(struct perf_event *event)
if (!(event->cpu < 0)) {
event->state = PERF_EVENT_STATE_OFF;
event->attr.constraint_duplicate = 1;
+ err = -EPERM;
}
}
out:
2017-11-07 17:32:46 -05:00
diff --git a/arch/arm/mach-msm/perf_event_msm_l2.c b/arch/arm/mach-msm/perf_event_msm_l2.c
index f78487a..93695e2 100644
--- a/arch/arm/mach-msm/perf_event_msm_l2.c
+++ b/arch/arm/mach-msm/perf_event_msm_l2.c
@@ -836,8 +836,10 @@ static int msm_l2_test_set_ev_constraint(struct perf_event *event)
* This sets the event OFF on all but one
* CPU.
*/
- if (!(event->cpu < 0))
+ if (!(event->cpu < 0)) {
event->state = PERF_EVENT_STATE_OFF;
+ err = -EPERM;
+ }
}
out:
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 33ad70a..7ebe09a 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -3030,13 +3030,6 @@ static void put_event(struct perf_event *event)
if (!atomic_long_dec_and_test(&event->refcount))
return;
- /*
- * Event can be in state OFF because of a constraint check.
- * Change to ACTIVE so that it gets cleaned up correctly.
- */
- if ((event->state == PERF_EVENT_STATE_OFF) &&
- event->attr.constraint_duplicate)
- event->state = PERF_EVENT_STATE_ACTIVE;
rcu_read_lock();
owner = ACCESS_ONCE(event->owner);
--
cgit v1.1