firmware: qemu_fw_cfg: misc bug fixes
Subsystems (2)
cover firmware: qemu_fw_cfg: misc bug fixes
When searching for the latest umn.edu patches I stumbled upon a recently submitted fix for a bug purportedly introduced by umn.edu:
https://lore.kernel.org/r/[email protected]
The patch in question is obviously bogus, but a closer look at the function in question revealed a number of other bugs, including one that was indeed introduced by umn.edu but that was missed during the (re-)review.
Included is also a related clean up.
Johan
Johan Hovold (4):
firmware: qemu_fw_cfg: fix NULL-pointer deref on duplicate entries
firmware: qemu_fw_cfg: fix kobject leak in probe error path
firmware: qemu_fw_cfg: fix sysfs information leak
firmware: qemu_fw_cfg: remove sysfs entries explicitly
drivers/firmware/qemu_fw_cfg.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-)
Signature · 1 line
2.32.0
PATCH 1/4 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]
--- drivers/firmware/qemu_fw_cfg.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-)
drivers/firmware/qemu_fw_cfg.c +1 -4
@@ -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); }
Signature · 1 line
2.32.0
PATCH 2/4 firmware: qemu_fw_cfg: fix kobject leak in probe error path
In reply to Johan HovoldAn initialised kobject must be freed using kobject_put() to avoid leaking associated resources (e.g. the object name).
Commit fe3c60684377 ("firmware: Fix a reference count leak.") "fixed" the leak in the first error path of the file registration helper but left the second one unchanged. This "fix" would however result in a NULL pointer dereference due to the release function also removing the never added entry from the fw_cfg_entry_cache list. This has now been addressed.
Fix the remaining kobject leak by restoring the common error path and adding the missing kobject_put().
--- drivers/firmware/qemu_fw_cfg.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-)
drivers/firmware/qemu_fw_cfg.c +6 -7
@@ -603,15 +603,13 @@ static int fw_cfg_register_file(const struct fw_cfg_file *f)/* register entry under "/sys/firmware/qemu_fw_cfg/by_key/" */ err =kobject_init_and_add (&entry->kobj, &fw_cfg_sysfs_entry_ktype, fw_cfg_sel_ko,"%d" , entry->select); -if (err) { -kobject_put (&entry->kobj); -return err; - } +if (err) + goto err_put_entry;/* add raw binary content access */ err =sysfs_create_bin_file (&entry->kobj, &fw_cfg_sysfs_attr_raw);if (err) - goto err_add_raw; + goto err_del_entry;/* try adding "/sys/firmware/qemu_fw_cfg/by_name/" symlink */ fw_cfg_build_symlink (fw_cfg_fname_kset, &entry->kobj, entry->name);
@@ -620,9 +618,10 @@ static int fw_cfg_register_file(const struct fw_cfg_file *f)fw_cfg_sysfs_cache_enlist (entry);return 0 ; -err_add_raw: +err_del_entry:kobject_del (&entry->kobj); -kfree (entry); +err_put_entry: +kobject_put (&entry->kobj);return err; }
Signature · 1 line
2.32.0
PATCH 3/4 firmware: qemu_fw_cfg: fix sysfs information leak
In reply to Johan HovoldMake sure to always NUL-terminate file names retrieved from the firmware to avoid accessing data beyond the entry slab buffer and exposing it through sysfs in case the firmware data is corrupt.
--- drivers/firmware/qemu_fw_cfg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/firmware/qemu_fw_cfg.c +1 -1
@@ -598,7 +598,7 @@ static int fw_cfg_register_file(const struct fw_cfg_file *f)/* set file entry information */ entry->size =be32_to_cpu (f->size); entry->select =be16_to_cpu (f->select); -memcpy (entry->name, f->name,FW_CFG_MAX_FILE_PATH ); +strscpy (entry->name, f->name,FW_CFG_MAX_FILE_PATH );/* register entry under "/sys/firmware/qemu_fw_cfg/by_key/" */ err = kobject_init_and_add(&entry->kobj, &fw_cfg_sysfs_entry_ktype,
Signature · 1 line
2.32.0
PATCH 4/4 firmware: qemu_fw_cfg: remove sysfs entries explicitly
In reply to Johan HovoldExplicitly remove the file entries from sysfs before dropping the final reference for symmetry reasons and for consistency with the rest of the driver.
--- drivers/firmware/qemu_fw_cfg.c | 1 + 1 file changed, 1 insertion(+)
drivers/firmware/qemu_fw_cfg.c +1 -0
@@ -389,6 +389,7 @@ static void fw_cfg_sysfs_cache_cleanup(void)list_for_each_entry_safe (entry, next, &fw_cfg_entry_cache, list) {fw_cfg_sysfs_cache_delist (entry); +kobject_del (&entry->kobj);kobject_put (&entry->kobj); } }
Signature · 1 line
2.32.0