drivers/base/faux.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-)
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).
Fixes: 61b76d07d2b4 ("driver core: faux: stop using static struct device")
Cc: stable@vger.kernel.org # 7.0
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Johan Hovold <johan@kernel.org>
---
drivers/base/faux.c | 19 +++++++------------
1 file changed, 7 insertions(+), 12 deletions(-)
diff --git a/drivers/base/faux.c b/drivers/base/faux.c
index fb3e42f21362..402ed119dfdf 100644
--- a/drivers/base/faux.c
+++ b/drivers/base/faux.c
@@ -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;
}
--
2.53.0
On Fri Apr 24, 2026 at 12:22 PM CEST, Johan Hovold wrote:
> diff --git a/drivers/base/faux.c b/drivers/base/faux.c
> index fb3e42f21362..402ed119dfdf 100644
> --- a/drivers/base/faux.c
> +++ b/drivers/base/faux.c
> @@ -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.
> +
> 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;
> }
> --
> 2.53.0
On Fri, Apr 24, 2026 at 01:42:12PM +0200, Danilo Krummrich wrote: > On Fri Apr 24, 2026 at 12:22 PM CEST, Johan Hovold wrote: > > diff --git a/drivers/base/faux.c b/drivers/base/faux.c > > index fb3e42f21362..402ed119dfdf 100644 > > --- a/drivers/base/faux.c > > +++ b/drivers/base/faux.c > > @@ -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. 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
On Fri, Apr 24, 2026 at 12:22:31PM +0200, Johan Hovold wrote: > 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! > 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
© 2016 - 2026 Red Hat, Inc.