[v1,1/2] driver core: class: Clear private pointer on registration failures

Message ID 4463268.LvFx2qVVIh@kreacher
State New
Headers
Series driver core/thermal: Fail registration of thermal object when thermal_class is not registered |

Commit Message

Rafael J. Wysocki Jan. 20, 2023, 7:46 p.m. UTC
  From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

Clear the class private pointer if __class_register() fails for it, so
as to allow its users to verify that the class is usable by checking
the value of that pointer.

For consistency, clear that pointer before freeing the object pointed
to by it in class_release().

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/base/class.c |   16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)
  

Comments

Daniel Lezcano Jan. 20, 2023, 10:43 p.m. UTC | #1
On 20/01/2023 20:46, Rafael J. Wysocki wrote:
> From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> 
> Clear the class private pointer if __class_register() fails for it, so
> as to allow its users to verify that the class is usable by checking
> the value of that pointer.
> 
> For consistency, clear that pointer before freeing the object pointed
> to by it in class_release().
> 
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> ---

Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>
  

Patch

Index: linux-pm/drivers/base/class.c
===================================================================
--- linux-pm.orig/drivers/base/class.c
+++ linux-pm/drivers/base/class.c
@@ -53,6 +53,8 @@  static void class_release(struct kobject
 
 	pr_debug("class '%s': release.\n", class->name);
 
+	class->p = NULL;
+
 	if (class->class_release)
 		class->class_release(class);
 	else
@@ -186,17 +188,21 @@  int __class_register(struct class *cls,
 	cls->p = cp;
 
 	error = kset_register(&cp->subsys);
-	if (error) {
-		kfree(cp);
-		return error;
-	}
+	if (error)
+		goto err_out;
+
 	error = class_add_groups(class_get(cls), cls->class_groups);
 	class_put(cls);
 	if (error) {
 		kobject_del(&cp->subsys.kobj);
 		kfree_const(cp->subsys.kobj.name);
-		kfree(cp);
+		goto err_out;
 	}
+	return 0;
+
+err_out:
+	kfree(cp);
+	cls->p = NULL;
 	return error;
 }
 EXPORT_SYMBOL_GPL(__class_register);