|
Tony Jones |
40c1d3 |
From: Kan Liang <kan.liang@linux.intel.com>
|
|
Tony Jones |
40c1d3 |
Date: Fri, 12 Mar 2021 05:21:37 -0800
|
|
Tony Jones |
40c1d3 |
Subject: perf/x86/intel: Fix a crash caused by zero PEBS status
|
|
Tony Jones |
40c1d3 |
Git-commit: d88d05a9e0b6d9356e97129d4ff9942d765f46ea
|
|
Tony Jones |
40c1d3 |
Patch-mainline: v5.12-rc4
|
|
Tony Jones |
40c1d3 |
References: CVE-2021-28971 bsc#1184196
|
|
Tony Jones |
40c1d3 |
|
|
Tony Jones |
40c1d3 |
A repeatable crash can be triggered by the perf_fuzzer on some Haswell
|
|
Tony Jones |
40c1d3 |
system.
|
|
Tony Jones |
40c1d3 |
https://lore.kernel.org/lkml/7170d3b-c17f-1ded-52aa-cc6d9ae999f4@maine.edu/
|
|
Tony Jones |
40c1d3 |
|
|
Tony Jones |
40c1d3 |
For some old CPUs (HSW and earlier), the PEBS status in a PEBS record
|
|
Tony Jones |
40c1d3 |
may be mistakenly set to 0. To minimize the impact of the defect, the
|
|
Tony Jones |
40c1d3 |
commit was introduced to try to avoid dropping the PEBS record for some
|
|
Tony Jones |
40c1d3 |
cases. It adds a check in the intel_pmu_drain_pebs_nhm(), and updates
|
|
Tony Jones |
40c1d3 |
the local pebs_status accordingly. However, it doesn't correct the PEBS
|
|
Tony Jones |
40c1d3 |
status in the PEBS record, which may trigger the crash, especially for
|
|
Tony Jones |
40c1d3 |
the large PEBS.
|
|
Tony Jones |
40c1d3 |
|
|
Tony Jones |
40c1d3 |
It's possible that all the PEBS records in a large PEBS have the PEBS
|
|
Tony Jones |
40c1d3 |
status 0. If so, the first get_next_pebs_record_by_bit() in the
|
|
Tony Jones |
40c1d3 |
__intel_pmu_pebs_event() returns NULL. The at = NULL. Since it's a large
|
|
Tony Jones |
40c1d3 |
PEBS, the 'count' parameter must > 1. The second
|
|
Tony Jones |
40c1d3 |
get_next_pebs_record_by_bit() will crash.
|
|
Tony Jones |
40c1d3 |
|
|
Tony Jones |
40c1d3 |
Besides the local pebs_status, correct the PEBS status in the PEBS
|
|
Tony Jones |
40c1d3 |
record as well.
|
|
Tony Jones |
40c1d3 |
|
|
Tony Jones |
40c1d3 |
Fixes: 01330d7288e0 ("perf/x86: Allow zero PEBS status with only single active event")
|
|
Tony Jones |
40c1d3 |
Reported-by: Vince Weaver <vincent.weaver@maine.edu>
|
|
Tony Jones |
40c1d3 |
Suggested-by: Peter Zijlstra (Intel) <peterz@infradead.org>
|
|
Tony Jones |
40c1d3 |
Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
|
|
Tony Jones |
40c1d3 |
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
|
|
Tony Jones |
40c1d3 |
Cc: stable@vger.kernel.org
|
|
Tony Jones |
40c1d3 |
Link: https://lkml.kernel.org/r/1615555298-140216-1-git-send-email-kan.liang@linux.intel.com
|
|
Tony Jones |
40c1d3 |
|
|
Tony Jones |
40c1d3 |
Signed-off-by: Tony Jones <tonyj@suse.de>
|
|
Tony Jones |
40c1d3 |
---
|
|
Tony Jones |
40c1d3 |
arch/x86/events/intel/ds.c | 2 +-
|
|
Tony Jones |
40c1d3 |
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
Tony Jones |
40c1d3 |
|
|
Tony Jones |
40c1d3 |
diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c
|
|
Tony Jones |
40c1d3 |
index 7ebae1826403..d32b302719fe 100644
|
|
Tony Jones |
40c1d3 |
--- a/arch/x86/events/intel/ds.c
|
|
Tony Jones |
40c1d3 |
+++ b/arch/x86/events/intel/ds.c
|
|
Tony Jones |
40c1d3 |
@@ -2010,7 +2010,7 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs, struct perf_sample_d
|
|
Tony Jones |
40c1d3 |
*/
|
|
Tony Jones |
40c1d3 |
if (!pebs_status && cpuc->pebs_enabled &&
|
|
Tony Jones |
40c1d3 |
!(cpuc->pebs_enabled & (cpuc->pebs_enabled-1)))
|
|
Tony Jones |
40c1d3 |
- pebs_status = cpuc->pebs_enabled;
|
|
Tony Jones |
40c1d3 |
+ pebs_status = p->status = cpuc->pebs_enabled;
|
|
Tony Jones |
40c1d3 |
|
|
Tony Jones |
40c1d3 |
bit = find_first_bit((unsigned long *)&pebs_status,
|
|
Tony Jones |
40c1d3 |
x86_pmu.max_pebs_events);
|
|
Tony Jones |
40c1d3 |
|