Skip to content

Commit e1ebd0e

Browse files
committed
powerpc/perf: Fix kernel address leak via sampling registers
Current code in power_pmu_disable() does not clear the sampling registers like Sampling Instruction Address Register (SIAR) and Sampling Data Address Register (SDAR) after disabling the PMU. Since these are userspace readable and could contain kernel addresses, add code to explicitly clear the content of these registers. Also add a "context synchronizing instruction" to enforce no further updates to these registers as suggested by Power ISA v3.0B. From section 9.4, on page 1108: "If an mtspr instruction is executed that changes the value of a Performance Monitor register other than SIAR, SDAR, and SIER, the change is not guaranteed to have taken effect until after a subsequent context synchronizing instruction has been executed (see Chapter 11. "Synchronization Requirements for Context Alterations" on page 1133)." Signed-off-by: Madhavan Srinivasan <[email protected]> [mpe: Massage change log and add ISA reference] Signed-off-by: Michael Ellerman <[email protected]>
1 parent dbfcf3c commit e1ebd0e

File tree

1 file changed

+15
-0
lines changed

1 file changed

+15
-0
lines changed

arch/powerpc/perf/core-book3s.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1226,6 +1226,7 @@ static void power_pmu_disable(struct pmu *pmu)
12261226
*/
12271227
write_mmcr0(cpuhw, val);
12281228
mb();
1229+
isync();
12291230

12301231
/*
12311232
* Disable instruction sampling if it was enabled
@@ -1234,12 +1235,26 @@ static void power_pmu_disable(struct pmu *pmu)
12341235
mtspr(SPRN_MMCRA,
12351236
cpuhw->mmcr[2] & ~MMCRA_SAMPLE_ENABLE);
12361237
mb();
1238+
isync();
12371239
}
12381240

12391241
cpuhw->disabled = 1;
12401242
cpuhw->n_added = 0;
12411243

12421244
ebb_switch_out(mmcr0);
1245+
1246+
#ifdef CONFIG_PPC64
1247+
/*
1248+
* These are readable by userspace, may contain kernel
1249+
* addresses and are not switched by context switch, so clear
1250+
* them now to avoid leaking anything to userspace in general
1251+
* including to another process.
1252+
*/
1253+
if (ppmu->flags & PPMU_ARCH_207S) {
1254+
mtspr(SPRN_SDAR, 0);
1255+
mtspr(SPRN_SIAR, 0);
1256+
}
1257+
#endif
12431258
}
12441259

12451260
local_irq_restore(flags);

0 commit comments

Comments
 (0)