]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
cpuidle: Fix kobject memory leaks in error paths
authorAnel Orazgaliyeva <anelkz@amazon.de>
Mon, 6 Sep 2021 18:34:40 +0000 (18:34 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 26 Nov 2021 10:58:39 +0000 (11:58 +0100)
[ 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

index e7e92ed34f0c6262d9876fecb162ecd5c934c065..34c4a61a954fc9221a7730c1b1a838b80469e872 100644 (file)
@@ -413,6 +413,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;
                }
                kobject_uevent(&kobj->kobj, KOBJ_ADD);
@@ -543,6 +544,7 @@ static int cpuidle_add_driver_sysfs(struct cpuidle_device *dev)
                                   &kdev->kobj, "driver");
        if (ret) {
                kobject_put(&kdrv->kobj);
+               kfree(kdrv);
                return ret;
        }
 
@@ -629,7 +631,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);
 
@@ -637,9 +638,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;