patch "driver core: Don't ignore class_dir_create_and_add() failure." added to driver-core-next
Subsystems (2)
This is a note to let you know that I've just added the patch titled
driver core: Don't ignore class_dir_create_and_add() failure.
to my driver-core git tree which can be found at
git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git
in the driver-core-next branch.
The patch will show up in the next release of the linux-next tree (usually sometime within the next 24 hours during the week.)
The patch will also be merged in the next major kernel release during the merge window.
If you have any questions about this process, please let me know.
Quoted 1 line
From
84d0c27d6233a9ba0578b20f5a09701eb66cee42Mon Sep 17 00:00:00 2001
From: Tetsuo Handa <[email protected]>
Date: Mon, 7 May 2018 19:10:31 +0900
Subject: 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
--- drivers/base/core.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
drivers/base/core.c +12 -2
@@ -1467,7 +1467,7 @@ class_dir_create_and_add(struct class *class, struct kobject *parent_kobj) dir =kzalloc (sizeof (*dir),GFP_KERNEL );if (!dir) -return NULL ; +return ERR_PTR (-ENOMEM ); dir->class = class;kobject_init (&dir->kobj, &class_dir_ktype);
@@ -1477,7 +1477,7 @@ class_dir_create_and_add(struct class *class, struct kobject *parent_kobj) retval =kobject_add (&dir->kobj, parent_kobj,"%s" , class->name);if (retval <0 ) {kobject_put (&dir->kobj); -return NULL ; +return ERR_PTR (retval); }return &dir->kobj; }
@@ -1784,6 +1784,10 @@ int device_add(struct device *dev) parent =get_device (dev->parent); kobj =get_device_parent (dev, parent); +if (IS_ERR (kobj)) { + error =PTR_ERR (kobj); + goto parent_error; + }if (kobj) dev->kobj.parent = kobj;
@@ -1882,6 +1886,7 @@ int device_add(struct device *dev)kobject_del (&dev->kobj); Error:cleanup_glue_dir (dev, glue_dir); +parent_error:put_device (parent); name_error:kfree (dev->p);
@@ -2701,6 +2706,11 @@ int device_move(struct device *dev, struct device *new_parent,device_pm_lock (); new_parent =get_device (new_parent); new_parent_kobj =get_device_parent (dev, new_parent); +if (IS_ERR (new_parent_kobj)) { + error =PTR_ERR (new_parent_kobj); +put_device (new_parent); + goto out; + }pr_debug ("device: '%s': %s: moving to '%s'\n" ,dev_name (dev), __func__, new_parent ?dev_name (new_parent) :"<NULL>" );
Signature · 1 line
2.17.0