drivers/cpufreq/cpufreq_governor.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
When kobject_init_and_add() fails, cpufreq_dbs_governor_init() calls
kobject_put(&dbs_data->attr_set.kobj).
The kobject release callback cpufreq_dbs_data_release() calls
gov->exit(dbs_data) and kfree(dbs_data), but the current error path
then calls gov->exit(dbs_data) and kfree(dbs_data) again, causing a
double free.
Keep the direct kfree(dbs_data) for the gov->init() failure path, but
after kobject_init_and_add() has been called, let kobject_put() handle
the cleanup through cpufreq_dbs_data_release().
Fixes: 4ebe36c94aed ("cpufreq: Fix kobject memleak")
Cc: stable@vger.kernel.org
Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
---
drivers/cpufreq/cpufreq_governor.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c
index 1a7fcaf39cc9..3ad51a986781 100644
--- a/drivers/cpufreq/cpufreq_governor.c
+++ b/drivers/cpufreq/cpufreq_governor.c
@@ -468,13 +468,13 @@ int cpufreq_dbs_governor_init(struct cpufreq_policy *policy)
/* Failure, so roll back. */
pr_err("initialization failed (dbs_data kobject init error %d)\n", ret);
- kobject_put(&dbs_data->attr_set.kobj);
-
policy->governor_data = NULL;
if (!have_governor_per_policy())
gov->gdbs_data = NULL;
- gov->exit(dbs_data);
+
+ kobject_put(&dbs_data->attr_set.kobj);
+ goto free_policy_dbs_info;
free_dbs_data:
kfree(dbs_data);
--
2.43.0
On 01-04-26, 10:45, Guangshuo Li wrote:
> When kobject_init_and_add() fails, cpufreq_dbs_governor_init() calls
> kobject_put(&dbs_data->attr_set.kobj).
>
> The kobject release callback cpufreq_dbs_data_release() calls
> gov->exit(dbs_data) and kfree(dbs_data), but the current error path
> then calls gov->exit(dbs_data) and kfree(dbs_data) again, causing a
> double free.
>
> Keep the direct kfree(dbs_data) for the gov->init() failure path, but
> after kobject_init_and_add() has been called, let kobject_put() handle
> the cleanup through cpufreq_dbs_data_release().
>
> Fixes: 4ebe36c94aed ("cpufreq: Fix kobject memleak")
> Cc: stable@vger.kernel.org
> Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
> ---
> drivers/cpufreq/cpufreq_governor.c | 6 +++---
> 1 file changed, 3 insertions(+), 3 deletions(-)
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
--
viresh
On Wed, Apr 1, 2026 at 8:23 AM Viresh Kumar <viresh.kumar@linaro.org> wrote:
>
> On 01-04-26, 10:45, Guangshuo Li wrote:
> > When kobject_init_and_add() fails, cpufreq_dbs_governor_init() calls
> > kobject_put(&dbs_data->attr_set.kobj).
> >
> > The kobject release callback cpufreq_dbs_data_release() calls
> > gov->exit(dbs_data) and kfree(dbs_data), but the current error path
> > then calls gov->exit(dbs_data) and kfree(dbs_data) again, causing a
> > double free.
> >
> > Keep the direct kfree(dbs_data) for the gov->init() failure path, but
> > after kobject_init_and_add() has been called, let kobject_put() handle
> > the cleanup through cpufreq_dbs_data_release().
> >
> > Fixes: 4ebe36c94aed ("cpufreq: Fix kobject memleak")
> > Cc: stable@vger.kernel.org
> > Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
> > ---
> > drivers/cpufreq/cpufreq_governor.c | 6 +++---
> > 1 file changed, 3 insertions(+), 3 deletions(-)
>
> Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Applied as 7.0-rc material, thanks!
On 4/1/2026 10:45 AM, Guangshuo Li wrote:
> When kobject_init_and_add() fails, cpufreq_dbs_governor_init() calls
> kobject_put(&dbs_data->attr_set.kobj).
>
> The kobject release callback cpufreq_dbs_data_release() calls
> gov->exit(dbs_data) and kfree(dbs_data), but the current error path
> then calls gov->exit(dbs_data) and kfree(dbs_data) again, causing a
> double free.
>
> Keep the direct kfree(dbs_data) for the gov->init() failure path, but
> after kobject_init_and_add() has been called, let kobject_put() handle
> the cleanup through cpufreq_dbs_data_release().
>
> Fixes: 4ebe36c94aed ("cpufreq: Fix kobject memleak")
> Cc: stable@vger.kernel.org
> Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
Thanks for the good catch and fix — this aligns with an issue I noticed
recently and looks reasonable to me.
Reviewed-by: Zhongqiu Han <zhongqiu.han@oss.qualcomm.com>
> ---
> drivers/cpufreq/cpufreq_governor.c | 6 +++---
> 1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c
> index 1a7fcaf39cc9..3ad51a986781 100644
> --- a/drivers/cpufreq/cpufreq_governor.c
> +++ b/drivers/cpufreq/cpufreq_governor.c
> @@ -468,13 +468,13 @@ int cpufreq_dbs_governor_init(struct cpufreq_policy *policy)
> /* Failure, so roll back. */
> pr_err("initialization failed (dbs_data kobject init error %d)\n", ret);
>
> - kobject_put(&dbs_data->attr_set.kobj);
> -
> policy->governor_data = NULL;
>
> if (!have_governor_per_policy())
> gov->gdbs_data = NULL;
> - gov->exit(dbs_data);
> +
> + kobject_put(&dbs_data->attr_set.kobj);
> + goto free_policy_dbs_info;
>
> free_dbs_data:
> kfree(dbs_data);
--
Thx and BRs,
Zhongqiu Han
© 2016 - 2026 Red Hat, Inc.