]> www.infradead.org Git - users/dwmw2/linux.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:36:08 +0000 (11:36 +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 66979dc3368074524fc40650a929932520f497fa..d9b917529abaf21ae660d504ad9dbebfcdc518e8 100644 (file)
@@ -468,6 +468,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);
@@ -599,6 +600,7 @@ static int cpuidle_add_driver_sysfs(struct cpuidle_device *dev)
                                   &kdev->kobj, "driver");
        if (ret) {
                kobject_put(&kdrv->kobj);
+               kfree(kdrv);
                return ret;
        }
 
@@ -685,7 +687,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);
 
@@ -693,9 +694,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;