Messages in this thread Patch in this message | | | Date | Wed, 15 Oct 2014 14:42:28 +0800 | From | Weng Meiling <> | Subject | Subject: [PATCH] kobject: fix the race between kobject_del and get_device_parent |
| |
When the last child kobject was deleted, it's parent kobject will be deleted, when removing the parent kobject if the parent kobject's sd has been set NULL and still not been removed from it's kset's list, at the same time another one trigger an device adding event, the function get_parent_device() will get the parent object from the kset's list for kobject_add(), but this time parent kobject's sd has been NULL. This race will make the sysfs_create_dir() return ENOENT, the new kobject will be failed to added into sysfs and trigger BUG() when creating attribute group under the new device's directory. So move the kobject removal from kset's list before kobj->sd=NULL.
The race situation:
path0(remove parent kobj, e.g:/sys/devices/virtual/block/) path1(register a new device)
kobject_del(){ get_device_parent(){ ... ... sysfs_remove_dir(kobj); //kobj->sd=NULL spin_lock(&dev->class->p->glue_dirs.list_lock); ... <=== list_for_each_entry(k, &dev->class->p->glue_dirs.list, entry) kobj_kset_leave(kobj); //remove kobj from kset list ... } }
We had triggered the bug, the detail message link: https://lkml.org/lkml/2014/10/13/40
Signed-off-by: Weng Meiling <wengmeiling.weng@huawei.com> --- lib/kobject.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/lib/kobject.c b/lib/kobject.c index 58751bb..af2b7bb 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -560,12 +560,13 @@ void kobject_del(struct kobject *kobj) if (!kobj) return;
+ kobj_kset_leave(kobj); + sd = kobj->sd; sysfs_remove_dir(kobj); sysfs_put(sd);
kobj->state_in_sysfs = 0; - kobj_kset_leave(kobj); kobject_put(kobj->parent); kobj->parent = NULL; } -- 1.8.2.2
| |