I'm not really a security researcher, so hopefully I'm reporting this in
the proper way.
I have a fuzzer tool for the perf_event_open() syscall that found
a few oopses on the ARM platform, which I reported to lkml a week ago.
One of the oopses can lead to a local privilege escalation on ARM-perf.
This fix can be found here:
http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=7809/1
The discussion thread is:
https://lkml.org/lkml/2013/8/7/259
The hope is this appears in 3.11-rc6 but my attempts to get the people at
security () vger kernel org to take this seriously didn't really go very
well.
I do have code that will exploit the kernel and give me a root shell
on an ARM Pandaboard machine running 3.11-rc4. The exploit is a bit
fragile though:
+ Only works on ARM
+ Elevates from normal user to root, no special config required.
perf_event syscalls run as regular users, not sure why some
think you need root.
+ It does need a user-mappable address at an exact byte offset
from a pmu_struct in memory. This limits things somewhat; in
my testing 3.11-rc kernels have INT_MIN at exactly the right place
but the exploit doesn't work on a 3.7.6 kernel,
it just oopses or crashes the machine.
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
index d9f5cd4..0500f10b 100644
--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
@@ -253,6 +253,9 @@ validate_event(struct pmu_hw_events *hw_events,
struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
struct pmu *leader_pmu = event->group_leader->pmu;
+ if (is_software_event(event))
+ return 1;
+
if (event->pmu != leader_pmu || event->state < PERF_EVENT_STATE_OFF)
return 1;