aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohan Hovold <[email protected]>2021-12-01 14:25:25 +0100
committerMichael S. Tsirkin <[email protected]>2022-01-14 18:50:52 -0500
commitd3e305592d69e21e36b76d24ca3c01971a2d09be (patch)
treee285d91bda054ceebdc6eddc25992db0fa405539
parent28cc408be72cebb0f3fcc37bc74ab3196d4de726 (diff)
firmware: qemu_fw_cfg: fix NULL-pointer deref on duplicate entries
Commit fe3c60684377 ("firmware: Fix a reference count leak.") "fixed" a kobject leak in the file registration helper by properly calling kobject_put() for the entry in case registration of the object fails (e.g. due to a name collision). This would however result in a NULL pointer dereference when the release function tries to remove the never added entry from the fw_cfg_entry_cache list. Fix this by moving the list-removal out of the release function. Note that the offending commit was one of the benign looking umn.edu fixes which was reviewed but not reverted. [1][2] [1] https://lore.kernel.org/r/202105051005.49BFABCE@keescook [2] https://lore.kernel.org/all/[email protected] Fixes: fe3c60684377 ("firmware: Fix a reference count leak.") Cc: [email protected] # 5.8 Cc: Qiushi Wu <[email protected]> Cc: Kees Cook <[email protected]> Cc: Greg Kroah-Hartman <[email protected]> Signed-off-by: Johan Hovold <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Michael S. Tsirkin <[email protected]>
-rw-r--r--drivers/firmware/qemu_fw_cfg.c5
1 files changed, 1 insertions, 4 deletions
diff --git a/drivers/firmware/qemu_fw_cfg.c b/drivers/firmware/qemu_fw_cfg.c
index 172c751a4f6c..a9c64ebfc49a 100644
--- a/drivers/firmware/qemu_fw_cfg.c
+++ b/drivers/firmware/qemu_fw_cfg.c
@@ -388,9 +388,7 @@ static void fw_cfg_sysfs_cache_cleanup(void)
struct fw_cfg_sysfs_entry *entry, *next;
list_for_each_entry_safe(entry, next, &fw_cfg_entry_cache, list) {
- /* will end up invoking fw_cfg_sysfs_cache_delist()
- * via each object's release() method (i.e. destructor)
- */
+ fw_cfg_sysfs_cache_delist(entry);
kobject_put(&entry->kobj);
}
}
@@ -448,7 +446,6 @@ static void fw_cfg_sysfs_release_entry(struct kobject *kobj)
{
struct fw_cfg_sysfs_entry *entry = to_entry(kobj);
- fw_cfg_sysfs_cache_delist(entry);
kfree(entry);
}