driver core: faux: fix root device registration
Subsystems (2)
Johan Hovold
maintainerPATCH 1/1 driver core: faux: fix root device registration
A recent change made the faux bus root device be allocated dynamically but failed to provide a release function to free the memory when the last reference is dropped (on theoretical failure to register the device or bus).
Fix this by using root_device_register() instead of open coding.
Also add the missing sanity check when registering faux devices to avoid a NULL-pointer dereference if the bus failed to register (which would previously have triggered a bunch of use-after-free warnings).
--- drivers/base/faux.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-)
drivers/base/faux.c +7 -12
@@ -133,6 +133,9 @@ struct faux_device *faux_device_create_with_groups(const char *name,struct device *dev;int ret; +if (IS_ERR_OR_NULL (faux_bus_root)) +return NULL ; + faux_obj =kzalloc_obj (*faux_obj);if (!faux_obj)return NULL ;
@@ -234,17 +237,9 @@ int __init faux_bus_init(void) {int ret; - faux_bus_root =kzalloc_obj (*faux_bus_root); -if (!faux_bus_root) -return -ENOMEM ; - -dev_set_name (faux_bus_root,"faux" ); - - ret =device_register (faux_bus_root); -if (ret) { -put_device (faux_bus_root); -return ret; - } + faux_bus_root =root_device_register ("faux" ); +if (IS_ERR (faux_bus_root)) +return PTR_ERR (faux_bus_root); ret =bus_register (&faux_bus_type);if (ret)
@@ -260,6 +255,6 @@ int __init faux_bus_init(void)bus_unregister (&faux_bus_type); error_bus: -device_unregister (faux_bus_root); +root_device_unregister (faux_bus_root);return ret; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerQuoted 6 lines · Johan Hovold
A recent change made the faux bus root device be allocated dynamically but failed to provide a release function to free the memory when the last reference is dropped (on theoretical failure to register the device or bus).
Fix this by using
root_device_register()instead of open coding.
Ah, good catch, I missed that, thanks!
Quoted 3 lines
Also add the missing sanity check when registering faux devices to avoid a NULL-pointer dereference if the bus failed to register (which would previously have triggered a bunch of use-after-free warnings).
If the bus fails to register at boot time, we have bigger problems than those types of warnings :)
I'll queue this up after -rc1 is out, thanks.
greg k-h
Danilo Krummrich
maintainerdrivers/base/faux.c struct faux_device *faux_device_create_with_groups(const char *name, · line 137
Quoted 10 lines · Johan Hovold
drivers/base/faux.c +2
-0@@ -133,6 +133,9 @@ struct faux_device *faux_device_create_with_groups(const char *name,struct device *dev;int ret; +if (IS_ERR_OR_NULL (faux_bus_root)) +return NULL ;
As Greg mentioned, if this happens we already have a much bigger fundamental problem earlier in the boot process.
Anyway, I think this check only catches when root_device_register() fails, but everything that comes after root_device_register() in faux_bus_init() still leaves us with a dangling pointer.
Quoted 35 lines
drivers/base/faux.c +5
-12+ faux_obj =kzalloc_obj (*faux_obj);if (!faux_obj)return NULL ;@@ -234,17 +237,9 @@ int __init faux_bus_init(void) {int ret; - faux_bus_root =kzalloc_obj (*faux_bus_root); -if (!faux_bus_root) -return -ENOMEM ; - -dev_set_name (faux_bus_root,"faux" ); - - ret =device_register (faux_bus_root); -if (ret) { -put_device (faux_bus_root); -return ret; - } + faux_bus_root =root_device_register ("faux" ); +if (IS_ERR (faux_bus_root)) +return PTR_ERR (faux_bus_root); ret =bus_register (&faux_bus_type);if (ret)@@ -260,6 +255,6 @@ int __init faux_bus_init(void)bus_unregister (&faux_bus_type); error_bus: -device_unregister (faux_bus_root); +root_device_unregister (faux_bus_root);return ret; }Signature · 1 line
2.53.0
Johan Hovold
maintainerQuoted 15 lines · Danilo Krummrich
drivers/base/faux.c struct faux_device *faux_device_create_with_groups(const char *name, · line 137
Quoted 10 lines · Johan Hovold
drivers/base/faux.c +2
-0@@ -133,6 +133,9 @@ struct faux_device *faux_device_create_with_groups(const char *name,struct device *dev;int ret; +if (IS_ERR_OR_NULL (faux_bus_root)) +return NULL ;As Greg mentioned, if this happens we already have a much bigger fundamental problem earlier in the boot process.
Quoted 3 lines
Anyway, I think this check only catches when
root_device_register()fails, but everything that comes afterroot_device_register()infaux_bus_init()still leaves us with a dangling pointer.
Indeed. I cleared the pointer in an earlier draft for this reason, but got side tracked and later found the change too invasive for something that would never happen in practise and somehow convinced myself that this check would do.
I'll respin.
Johan