Takashi Iwai d549bf
From 47a1db8e797da01a1309bf42e0c0d771d4e4d4f3 Mon Sep 17 00:00:00 2001
Takashi Iwai d549bf
From: Johan Hovold <johan@kernel.org>
Takashi Iwai d549bf
Date: Wed, 1 Dec 2021 14:25:26 +0100
Takashi Iwai d549bf
Subject: [PATCH] firmware: qemu_fw_cfg: fix kobject leak in probe error path
Takashi Iwai d549bf
Git-commit: 47a1db8e797da01a1309bf42e0c0d771d4e4d4f3
Takashi Iwai 8f947a
Alt-commit: 6004e351da50565fb561be85d45151dc9c370023
Takashi Iwai d549bf
Patch-mainline: v5.17-rc1
Takashi Iwai d549bf
References: git-fixes
Takashi Iwai d549bf
Takashi Iwai d549bf
An initialised kobject must be freed using kobject_put() to avoid
Takashi Iwai d549bf
leaking associated resources (e.g. the object name).
Takashi Iwai d549bf
Takashi Iwai d549bf
Commit fe3c60684377 ("firmware: Fix a reference count leak.") "fixed"
Takashi Iwai d549bf
the leak in the first error path of the file registration helper but
Takashi Iwai d549bf
left the second one unchanged. This "fix" would however result in a NULL
Takashi Iwai d549bf
pointer dereference due to the release function also removing the never
Takashi Iwai d549bf
added entry from the fw_cfg_entry_cache list. This has now been
Takashi Iwai d549bf
addressed.
Takashi Iwai d549bf
Takashi Iwai d549bf
Fix the remaining kobject leak by restoring the common error path and
Takashi Iwai d549bf
adding the missing kobject_put().
Takashi Iwai d549bf
Takashi Iwai d549bf
Fixes: 75f3e8e47f38 ("firmware: introduce sysfs driver for QEMU's fw_cfg device")
Takashi Iwai d549bf
Cc: stable@vger.kernel.org      # 4.6
Takashi Iwai d549bf
Cc: Gabriel Somlo <somlo@cmu.edu>
Takashi Iwai d549bf
Signed-off-by: Johan Hovold <johan@kernel.org>
Takashi Iwai d549bf
Link: https://lore.kernel.org/r/20211201132528.30025-3-johan@kernel.org
Takashi Iwai d549bf
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Takashi Iwai d549bf
Acked-by: Takashi Iwai <tiwai@suse.de>
Takashi Iwai d549bf
Takashi Iwai d549bf
---
Takashi Iwai d549bf
 drivers/firmware/qemu_fw_cfg.c | 13 ++++++-------
Takashi Iwai d549bf
 1 file changed, 6 insertions(+), 7 deletions(-)
Takashi Iwai d549bf
Takashi Iwai d549bf
diff --git a/drivers/firmware/qemu_fw_cfg.c b/drivers/firmware/qemu_fw_cfg.c
Takashi Iwai d549bf
index a9c64ebfc49a..ccb7ed62452f 100644
Takashi Iwai d549bf
--- a/drivers/firmware/qemu_fw_cfg.c
Takashi Iwai d549bf
+++ b/drivers/firmware/qemu_fw_cfg.c
Takashi Iwai d549bf
@@ -603,15 +603,13 @@ static int fw_cfg_register_file(const struct fw_cfg_file *f)
Takashi Iwai d549bf
 	/* register entry under "/sys/firmware/qemu_fw_cfg/by_key/" */
Takashi Iwai d549bf
 	err = kobject_init_and_add(&entry->kobj, &fw_cfg_sysfs_entry_ktype,
Takashi Iwai d549bf
 				   fw_cfg_sel_ko, "%d", entry->select);
Takashi Iwai d549bf
-	if (err) {
Takashi Iwai d549bf
-		kobject_put(&entry->kobj);
Takashi Iwai d549bf
-		return err;
Takashi Iwai d549bf
-	}
Takashi Iwai d549bf
+	if (err)
Takashi Iwai d549bf
+		goto err_put_entry;
Takashi Iwai d549bf
 
Takashi Iwai d549bf
 	/* add raw binary content access */
Takashi Iwai d549bf
 	err = sysfs_create_bin_file(&entry->kobj, &fw_cfg_sysfs_attr_raw);
Takashi Iwai d549bf
 	if (err)
Takashi Iwai d549bf
-		goto err_add_raw;
Takashi Iwai d549bf
+		goto err_del_entry;
Takashi Iwai d549bf
 
Takashi Iwai d549bf
 	/* try adding "/sys/firmware/qemu_fw_cfg/by_name/" symlink */
Takashi Iwai d549bf
 	fw_cfg_build_symlink(fw_cfg_fname_kset, &entry->kobj, entry->name);
Takashi Iwai d549bf
@@ -620,9 +618,10 @@ static int fw_cfg_register_file(const struct fw_cfg_file *f)
Takashi Iwai d549bf
 	fw_cfg_sysfs_cache_enlist(entry);
Takashi Iwai d549bf
 	return 0;
Takashi Iwai d549bf
 
Takashi Iwai d549bf
-err_add_raw:
Takashi Iwai d549bf
+err_del_entry:
Takashi Iwai d549bf
 	kobject_del(&entry->kobj);
Takashi Iwai d549bf
-	kfree(entry);
Takashi Iwai d549bf
+err_put_entry:
Takashi Iwai d549bf
+	kobject_put(&entry->kobj);
Takashi Iwai d549bf
 	return err;
Takashi Iwai d549bf
 }
Takashi Iwai d549bf
 
Takashi Iwai d549bf
-- 
Takashi Iwai d549bf
2.31.1
Takashi Iwai d549bf