[PATCH] perf/x86/rapl: Fix use-after-free on rapl_pmus_core on AMD/Hygon
From: Jayapal Ashwin Nair
Date: Tue Oct 13 2026 - 06:28:09 EST
The global rapl_pmus_core pointer can be used after it has been freed in
two ways:
1) init_rapl_pmus() stores the newly allocated rapl_pmus in
*rapl_pmus_ptr before calling init_rapl_pmu(). If init_rapl_pmu()
fails, rapl_pmus is freed but *rapl_pmus_ptr is not cleared, leaving
rapl_pmus_core pointing to freed memory. rapl_pmu_init() then jumps
to core_init_failed, where rapl_advertise() dereferences it.
2) If perf_pmu_register() fails for the power_core PMU,
cleanup_rapl_pmus() frees rapl_pmus_core, but the pointer is not
cleared. rapl_advertise() then dereferences the stale pointer in the
same way as in 1).
In both cases, rmmod can result in use-after-free and a double free.
Fix this by setting rapl_pmus_core to NULL on both failure paths.
Fixes: b4943b8bfc41 ("perf/x86/rapl: Add core energy counter support for AMD CPUs")
Signed-off-by: Jayapal Ashwin Nair <jayapalashwin.nair@xxxxxxx>
---
arch/x86/events/rapl.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/arch/x86/events/rapl.c b/arch/x86/events/rapl.c
index 8ed03c32f560..b67986c58146 100644
--- a/arch/x86/events/rapl.c
+++ b/arch/x86/events/rapl.c
@@ -763,8 +763,10 @@ static int __init init_rapl_pmus(struct rapl_pmus **rapl_pmus_ptr, int rapl_pmu_
rapl_pmus->pmu.capabilities = PERF_PMU_CAP_NO_EXCLUDE;
ret = init_rapl_pmu(rapl_pmus);
- if (ret)
+ if (ret) {
+ *rapl_pmus_ptr = NULL;
kfree(rapl_pmus);
+ }
return ret;
}
@@ -939,6 +941,7 @@ static int __init rapl_pmu_init(void)
if (ret) {
pr_warn("power-core PMU registration failed (%d)\n", ret);
cleanup_rapl_pmus(rapl_pmus_core);
+ rapl_pmus_core = NULL;
}
}
--
2.53.0