drivers/edac/edac_device_sysfs.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
If kobject_init_and_add() fails, the error path drops the kobject
reference with kobject_put(). This may call
edac_device_ctrl_master_release(), which drops the module reference and
frees the edac_device_ctl_info object.
However, the same error path then calls module_put(edac_dev->owner),
which dereferences edac_dev after it may have been freed. This can cause
a use-after-free and also drops the module reference twice.
Track whether kobject_init_and_add() has been called. If it has, rely on
the kobject release callback to drop the module reference. Otherwise,
drop the module reference directly.
This issue was found by a static analysis tool I am developing.
Fixes: 17ed808ad2431 ("EDAC: Fix reference count leaks")
Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
---
v2:
- Move kobj_initialized assignment to the kobject_init_and_add() call
site so it records whether the kobject has actually been initialized.
drivers/edac/edac_device_sysfs.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/edac/edac_device_sysfs.c b/drivers/edac/edac_device_sysfs.c
index fcebc4ffea26..042a30ed55c6 100644
--- a/drivers/edac/edac_device_sysfs.c
+++ b/drivers/edac/edac_device_sysfs.c
@@ -231,6 +231,7 @@ int edac_device_register_sysfs_main_kobj(struct edac_device_ctl_info *edac_dev)
struct device *dev_root;
const struct bus_type *edac_subsys;
int err = -ENODEV;
+ bool kobj_initialized = false;
edac_dbg(1, "\n");
@@ -256,6 +257,7 @@ int edac_device_register_sysfs_main_kobj(struct edac_device_ctl_info *edac_dev)
if (dev_root) {
err = kobject_init_and_add(&edac_dev->kobj, &ktype_device_ctrl,
&dev_root->kobj, "%s", edac_dev->name);
+ kobj_initialized = true;
put_device(dev_root);
}
if (err) {
@@ -275,8 +277,10 @@ int edac_device_register_sysfs_main_kobj(struct edac_device_ctl_info *edac_dev)
/* Error exit stack */
err_kobj_reg:
- kobject_put(&edac_dev->kobj);
- module_put(edac_dev->owner);
+ if (kobj_initialized)
+ kobject_put(&edac_dev->kobj);
+ else
+ module_put(edac_dev->owner);
err_out:
return err;
--
2.43.0
> From: Guangshuo Li <lgs201920130244@gmail.com>
> Sent: Wednesday, April 29, 2026 12:08 AM
> To: Borislav Petkov <bp@alien8.de>; Luck, Tony <tony.luck@intel.com>;
> Qiushi Wu <wu000273@umn.edu>; linux-edac@vger.kernel.org; linux-
> kernel@vger.kernel.org
> Cc: Guangshuo Li <lgs201920130244@gmail.com>
> Subject: [PATCH v2] EDAC/sysfs: Fix UAF in
> edac_device_register_sysfs_main_kobj()
>
> If kobject_init_and_add() fails, the error path drops the kobject reference with
> kobject_put(). This may call edac_device_ctrl_master_release(), which drops
> the module reference and frees the edac_device_ctl_info object.
>
> However, the same error path then calls module_put(edac_dev->owner),
> which dereferences edac_dev after it may have been freed. This can cause a
> use-after-free and also drops the module reference twice.
>
> Track whether kobject_init_and_add() has been called. If it has, rely on the
> kobject release callback to drop the module reference. Otherwise, drop the
> module reference directly.
>
> This issue was found by a static analysis tool I am developing.
>
> Fixes: 17ed808ad2431 ("EDAC: Fix reference count leaks")
> Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
LGTM,
Reviewed-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
© 2016 - 2026 Red Hat, Inc.