summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVinay Belgaumkar <vinay.belgaumkar@intel.com>2026-09-04 11:16:24 -0700
committerPeter Zijlstra <peterz@infradead.org>2026-09-18 12:19:43 +0200
commit88aed0422f39b22406f35f1e758cea25e7bbcfb5 (patch)
tree1a85c1427a685efa7260a8d3794abe78dd2a1ad7
parenta5f7a5bb3b7f28ba7e4fa246775b29a0e5537255 (diff)
downloadlinux-stable-88aed0422f39b22406f35f1e758cea25e7bbcfb5.tar.gz
linux-stable-88aed0422f39b22406f35f1e758cea25e7bbcfb5.zip
perf: Fix null pointer access in is_include_guest_event()
A typical module unload occurring event when there is an active perf connection leads to freeing of the pmu pointer. The call log is something like: .. __pmu_detach_event pmu_detach_event pmu_detach_events perf_pmu_unregister .. __pmu_detach_event() sets event->pmu to null. When the perf connection finally is closed, the following stack trace is observed: Oops: general protection fault, kernel NULL pointer dereference ... RIP: 0010:_free_event+0x3e/0x370 ... Call Trace: ... perf_event_release_kernel+0x260/0x2d0 perf_release+0x12/0x20 A call to mediated_pmu_unaccount_event() inside _free_event() is the root cause of this crash. Adding a check inside is_include_guest_event() ensures we don't accidentally access a null pmu ptr. In addition to this, we will now call mediated_pmu_unaccount_event() before clearing the pmu ptr so that nr_include_guest_events counts are maintained correctly. Fixes: eff95e170275 ("perf: Add APIs to create/release mediated guest vPMUs") Assisted-by: Claude:Claude-Sonnet-5 Signed-off-by: Vinay Belgaumkar <vinay.belgaumkar@intel.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com> Link: https://patch.msgid.link/20260904181625.1394082-1-vinay.belgaumkar@intel.com
-rw-r--r--kernel/events/core.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/kernel/events/core.c b/kernel/events/core.c
index fe33fe156..db7b76d6b 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -6350,6 +6350,9 @@ static DEFINE_MUTEX(perf_mediated_pmu_mutex);
/* !exclude_guest event of PMU with PERF_PMU_CAP_MEDIATED_VPMU */
static inline bool is_include_guest_event(struct perf_event *event)
{
+ if (!event->pmu)
+ return false;
+
if ((event->pmu->capabilities & PERF_PMU_CAP_MEDIATED_VPMU) &&
!event->attr.exclude_guest)
return true;
@@ -13002,6 +13005,7 @@ static void __pmu_detach_event(struct pmu *pmu, struct perf_event *event,
exclusive_event_destroy(event);
module_put(pmu->module);
+ mediated_pmu_unaccount_event(event);
event->pmu = NULL; /* force fault instead of UAF */
}