aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kernel/events/core.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 784ab8fe8714..22350b15b4e7 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -6410,6 +6410,21 @@ static void perf_log_itrace_start(struct perf_event *event)
perf_output_end(&handle);
}
+static bool sample_is_allowed(struct perf_event *event, struct pt_regs *regs)
+{
+ /*
+ * Due to interrupt latency (AKA "skid"), we may enter the
+ * kernel before taking an overflow, even if the PMU is only
+ * counting user events.
+ * To avoid leaking information to userspace, we must always
+ * reject kernel samples when exclude_kernel is set.
+ */
+ if (event->attr.exclude_kernel && !user_mode(regs))
+ return false;
+
+ return true;
+}
+
/*
* Generic event overflow handling, sampling.
*/
@@ -6457,6 +6472,12 @@ static int __perf_event_overflow(struct perf_event *event,
}
/*
+ * For security, drop the skid kernel samples if necessary.
+ */
+ if (!sample_is_allowed(event, regs))
+ return ret;
+
+ /*
* XXX event_limit might not quite work as expected on inherited
* events
*/