Skip to content

Commit 84d0c27

Browse files
Tetsuo Handagregkh
authored andcommitted
driver core: Don't ignore class_dir_create_and_add() failure.
syzbot is hitting WARN() at kernfs_add_one() [1]. This is because kernfs_create_link() is confused by previous device_add() call which continued without setting dev->kobj.parent field when get_device_parent() failed by memory allocation fault injection. Fix this by propagating the error from class_dir_create_and_add() to the calllers of get_device_parent(). [1] https://syzkaller.appspot.com/bug?id=fae0fb607989ea744526d1c082a5b8de6529116f Signed-off-by: Tetsuo Handa <[email protected]> Reported-by: syzbot <[email protected]> Cc: Greg Kroah-Hartman <[email protected]> Cc: stable <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent cd4846c commit 84d0c27

File tree

1 file changed

+12
-2
lines changed

1 file changed

+12
-2
lines changed

drivers/base/core.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1467,7 +1467,7 @@ class_dir_create_and_add(struct class *class, struct kobject *parent_kobj)
14671467

14681468
dir = kzalloc(sizeof(*dir), GFP_KERNEL);
14691469
if (!dir)
1470-
return NULL;
1470+
return ERR_PTR(-ENOMEM);
14711471

14721472
dir->class = class;
14731473
kobject_init(&dir->kobj, &class_dir_ktype);
@@ -1477,7 +1477,7 @@ class_dir_create_and_add(struct class *class, struct kobject *parent_kobj)
14771477
retval = kobject_add(&dir->kobj, parent_kobj, "%s", class->name);
14781478
if (retval < 0) {
14791479
kobject_put(&dir->kobj);
1480-
return NULL;
1480+
return ERR_PTR(retval);
14811481
}
14821482
return &dir->kobj;
14831483
}
@@ -1784,6 +1784,10 @@ int device_add(struct device *dev)
17841784

17851785
parent = get_device(dev->parent);
17861786
kobj = get_device_parent(dev, parent);
1787+
if (IS_ERR(kobj)) {
1788+
error = PTR_ERR(kobj);
1789+
goto parent_error;
1790+
}
17871791
if (kobj)
17881792
dev->kobj.parent = kobj;
17891793

@@ -1882,6 +1886,7 @@ int device_add(struct device *dev)
18821886
kobject_del(&dev->kobj);
18831887
Error:
18841888
cleanup_glue_dir(dev, glue_dir);
1889+
parent_error:
18851890
put_device(parent);
18861891
name_error:
18871892
kfree(dev->p);
@@ -2701,6 +2706,11 @@ int device_move(struct device *dev, struct device *new_parent,
27012706
device_pm_lock();
27022707
new_parent = get_device(new_parent);
27032708
new_parent_kobj = get_device_parent(dev, new_parent);
2709+
if (IS_ERR(new_parent_kobj)) {
2710+
error = PTR_ERR(new_parent_kobj);
2711+
put_device(new_parent);
2712+
goto out;
2713+
}
27042714

27052715
pr_debug("device: '%s': %s: moving to '%s'\n", dev_name(dev),
27062716
__func__, new_parent ? dev_name(new_parent) : "<NULL>");

0 commit comments

Comments
 (0)