Message ID | 20211210072858.20471-1-niejianglei2021@163.com |
---|---|
State | New |
Headers | show |
Series | powercap: DTPM: Fix reference leak in cpuhp_dtpm_cpu_offline() | expand |
diff --git a/drivers/powercap/dtpm_cpu.c b/drivers/powercap/dtpm_cpu.c index 51c366938acd..6c94515b21ef 100644 --- a/drivers/powercap/dtpm_cpu.c +++ b/drivers/powercap/dtpm_cpu.c @@ -156,21 +156,25 @@ static int cpuhp_dtpm_cpu_offline(unsigned int cpu) return 0; pd = em_cpu_get(cpu); - if (!pd) + if (!pd) { + cpufreq_cpu_put(policy); return -EINVAL; + } dtpm = per_cpu(dtpm_per_cpu, cpu); power_sub(dtpm, pd); - if (cpumask_weight(policy->cpus) != 1) + if (cpumask_weight(policy->cpus) != 1) { + cpufreq_cpu_put(policy); return 0; + } for_each_cpu(cpu, policy->related_cpus) per_cpu(dtpm_per_cpu, cpu) = NULL; dtpm_unregister(dtpm); - + cpufreq_cpu_put(policy); return 0; }
In line 153 (#1), cpufreq_cpu_get() increments the kobject reference counter of the policy it returned on success. According to the document, the policy returned by cpufreq_cpu_get() has to be released with the help of cpufreq_cpu_put() to balance its kobject reference counter properly. Forgetting the cpufreq_cpu_put() operation will result in reference leak.This bug influences all stable versions from v5.15 to v5.15.7. We can fix it by calling cpufreq_cpu_put() before the function returns (#2, #3 and #4). 147 static int cpuhp_dtpm_cpu_offline(unsigned int cpu) 148 { 153 policy = cpufreq_cpu_get(cpu); // #1: reference increment 155 if (!policy) 156 return 0; 158 pd = em_cpu_get(cpu); 159 if (!pd) 160 return -EINVAL; // #2: missing reference decrement 166 if (cpumask_weight(policy->cpus) != 1) 167 return 0; // #3: missing reference decrement 174 return 0; // #4: missing reference decrement 175 } Signed-off-by: Jianglei Nie <niejianglei2021@163.com> --- drivers/powercap/dtpm_cpu.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)