[PATCH v3] profiling: don't free prof_cpu_mask on init failure
Tristan Madani <[email protected]>
| Newsgroups | org.kernel.vger.stable,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
From: Tristan Madani <[email protected]> When profiling is enabled at runtime via /sys/kernel/profiling, profile_init() allocates prof_cpu_mask then attempts to allocate prof_buffer. If all prof_buffer allocations fail, the error path frees prof_cpu_mask but leaves prof_on set. Since profile_tick() runs from timer interrupt context and reads prof_cpu_mask on every tick, it can access the freed cpumask between the free and the next reboot. Don't free prof_cpu_mask in the error path. The cpumask allocation already succeeded and is small; keeping it on this rare failure path avoids the stale access without additional synchronization. Note: mainline removed prof_cpu_mask entirely in commit 7c51f7bbf057 ("profiling: remove prof_cpu_mask"). This is a minimal fix for stable trees where the variable is still present. Fixes: c309b917cab55 ("cpumask: convert kernel/profile.c") Cc: [email protected] Suggested-by: Tetsuo Handa <[email protected]> Signed-off-by: Tristan Madani <[email protected]> --- Changes in v3: - Added comment explaining deliberate leak (Andrew Morton) - Corrected Fixes tag from 22b8ce94708f to c309b917cab55 (Tetsuo Handa) - Added stable-only context in commit message Changes in v2: - Remove the free_cpumask_var() call instead of adding a prof_on guard in profile_tick(), which still raced with the free (Tetsuo Handa) kernel/profile.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/kernel/profile.c b/kernel/profile.c index 984f819b701c9..dcb65a2501558 100644 --- a/kernel/profile.c +++ b/kernel/profile.c @@ -123,7 +123,14 @@ int __ref profile_init(void) if (prof_buffer) return 0; - free_cpumask_var(prof_cpu_mask); + /* + * Do not free prof_cpu_mask here. profile_tick() accesses it from + * timer interrupt context without synchronization, so freeing it + * while prof_on is set leads to a stale read. The cpumask is small + * and this error path is rare, so the leak is harmless. + * This code was removed entirely by commit 7c51f7bbf057 + * ("profiling: remove prof_cpu_mask") in v6.11. + */ return -ENOMEM; } -- 2.47.3