Skip to content

Commit 4ef12f7

Browse files
Heikki Krogerusgregkh
authored andcommitted
kobject: Make sure the parent does not get released before its children
In the function kobject_cleanup(), kobject_del(kobj) is called before the kobj->release(). That makes it possible to release the parent of the kobject before the kobject itself. To fix that, adding function __kboject_del() that does everything that kobject_del() does except release the parent reference. kobject_cleanup() then calls __kobject_del() instead of kobject_del(), and separately decrements the reference count of the parent kobject after kobj->release() has been called. Reported-by: Naresh Kamboju <[email protected]> Reported-by: kernel test robot <[email protected]> Fixes: 7589238 ("Revert "software node: Simplify software_node_release() function"") Suggested-by: "Rafael J. Wysocki" <[email protected]> Signed-off-by: Heikki Krogerus <[email protected]> Reviewed-by: Rafael J. Wysocki <[email protected]> Reviewed-by: Brendan Higgins <[email protected]> Tested-by: Brendan Higgins <[email protected]> Acked-by: Randy Dunlap <[email protected]> Link: https://lore.kernel.org/r/[email protected] Cc: stable <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 44e9604 commit 4ef12f7

File tree

1 file changed

+20
-10
lines changed

1 file changed

+20
-10
lines changed

lib/kobject.c

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -599,14 +599,7 @@ int kobject_move(struct kobject *kobj, struct kobject *new_parent)
599599
}
600600
EXPORT_SYMBOL_GPL(kobject_move);
601601

602-
/**
603-
* kobject_del() - Unlink kobject from hierarchy.
604-
* @kobj: object.
605-
*
606-
* This is the function that should be called to delete an object
607-
* successfully added via kobject_add().
608-
*/
609-
void kobject_del(struct kobject *kobj)
602+
static void __kobject_del(struct kobject *kobj)
610603
{
611604
struct kernfs_node *sd;
612605
const struct kobj_type *ktype;
@@ -625,9 +618,23 @@ void kobject_del(struct kobject *kobj)
625618

626619
kobj->state_in_sysfs = 0;
627620
kobj_kset_leave(kobj);
628-
kobject_put(kobj->parent);
629621
kobj->parent = NULL;
630622
}
623+
624+
/**
625+
* kobject_del() - Unlink kobject from hierarchy.
626+
* @kobj: object.
627+
*
628+
* This is the function that should be called to delete an object
629+
* successfully added via kobject_add().
630+
*/
631+
void kobject_del(struct kobject *kobj)
632+
{
633+
struct kobject *parent = kobj->parent;
634+
635+
__kobject_del(kobj);
636+
kobject_put(parent);
637+
}
631638
EXPORT_SYMBOL(kobject_del);
632639

633640
/**
@@ -663,6 +670,7 @@ EXPORT_SYMBOL(kobject_get_unless_zero);
663670
*/
664671
static void kobject_cleanup(struct kobject *kobj)
665672
{
673+
struct kobject *parent = kobj->parent;
666674
struct kobj_type *t = get_ktype(kobj);
667675
const char *name = kobj->name;
668676

@@ -684,7 +692,7 @@ static void kobject_cleanup(struct kobject *kobj)
684692
if (kobj->state_in_sysfs) {
685693
pr_debug("kobject: '%s' (%p): auto cleanup kobject_del\n",
686694
kobject_name(kobj), kobj);
687-
kobject_del(kobj);
695+
__kobject_del(kobj);
688696
}
689697

690698
if (t && t->release) {
@@ -698,6 +706,8 @@ static void kobject_cleanup(struct kobject *kobj)
698706
pr_debug("kobject: '%s': free name\n", name);
699707
kfree_const(name);
700708
}
709+
710+
kobject_put(parent);
701711
}
702712

703713
#ifdef CONFIG_DEBUG_KOBJECT_RELEASE

0 commit comments

Comments
 (0)