| From 82b5ca4bc4da2b62c5a70784eeccb7a34d2abd5c Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Mon, 6 Sep 2021 18:34:40 +0000 |
| Subject: cpuidle: Fix kobject memory leaks in error paths |
| |
| From: Anel Orazgaliyeva <anelkz@amazon.de> |
| |
| [ Upstream commit e5f5a66c9aa9c331da5527c2e3fd9394e7091e01 ] |
| |
| Commit c343bf1ba5ef ("cpuidle: Fix three reference count leaks") |
| fixes the cleanup of kobjects; however, it removes kfree() calls |
| altogether, leading to memory leaks. |
| |
| Fix those and also defer the initialization of dev->kobj_dev until |
| after the error check, so that we do not end up with a dangling |
| pointer. |
| |
| Fixes: c343bf1ba5ef ("cpuidle: Fix three reference count leaks") |
| Signed-off-by: Anel Orazgaliyeva <anelkz@amazon.de> |
| Suggested-by: Aman Priyadarshi <apeureka@amazon.de> |
| [ rjw: Subject edits ] |
| Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/cpuidle/sysfs.c | 5 ++++- |
| 1 file changed, 4 insertions(+), 1 deletion(-) |
| |
| diff --git a/drivers/cpuidle/sysfs.c b/drivers/cpuidle/sysfs.c |
| index f8747322b3c70..e591f56f98c03 100644 |
| --- a/drivers/cpuidle/sysfs.c |
| +++ b/drivers/cpuidle/sysfs.c |
| @@ -481,6 +481,7 @@ static int cpuidle_add_state_sysfs(struct cpuidle_device *device) |
| &kdev->kobj, "state%d", i); |
| if (ret) { |
| kobject_put(&kobj->kobj); |
| + kfree(kobj); |
| goto error_state; |
| } |
| cpuidle_add_s2idle_attr_group(kobj); |
| @@ -612,6 +613,7 @@ static int cpuidle_add_driver_sysfs(struct cpuidle_device *dev) |
| &kdev->kobj, "driver"); |
| if (ret) { |
| kobject_put(&kdrv->kobj); |
| + kfree(kdrv); |
| return ret; |
| } |
| |
| @@ -698,7 +700,6 @@ int cpuidle_add_sysfs(struct cpuidle_device *dev) |
| if (!kdev) |
| return -ENOMEM; |
| kdev->dev = dev; |
| - dev->kobj_dev = kdev; |
| |
| init_completion(&kdev->kobj_unregister); |
| |
| @@ -706,9 +707,11 @@ int cpuidle_add_sysfs(struct cpuidle_device *dev) |
| "cpuidle"); |
| if (error) { |
| kobject_put(&kdev->kobj); |
| + kfree(kdev); |
| return error; |
| } |
| |
| + dev->kobj_dev = kdev; |
| kobject_uevent(&kdev->kobj, KOBJ_ADD); |
| |
| return 0; |
| -- |
| 2.33.0 |
| |