From: Manuel Estrada Sainz <ranty@ranty.pantax.net>

Based on patch and suggestions from Dmitry Torokhov

- release 'struct firmware_priv' from class_dev->release.


---

 25-akpm/drivers/base/firmware_class.c |   11 ++++++++---
 1 files changed, 8 insertions(+), 3 deletions(-)

diff -puN drivers/base/firmware_class.c~request_firmware-04-priv-leak-fix drivers/base/firmware_class.c
--- 25/drivers/base/firmware_class.c~request_firmware-04-priv-leak-fix	Tue Feb 24 17:55:50 2004
+++ 25-akpm/drivers/base/firmware_class.c	Tue Feb 24 17:55:50 2004
@@ -232,6 +232,9 @@ static struct bin_attribute firmware_att
 static void
 fw_class_dev_release(struct class_device *class_dev)
 {
+	struct firmware_priv *fw_priv = class_get_devdata(class_dev);
+
+	kfree(fw_priv);
 	kfree(class_dev);
 }
 
@@ -258,6 +261,8 @@ fw_setup_class_device(struct class_devic
 	struct class_device *class_dev = kmalloc(sizeof (struct class_device),
 						 GFP_KERNEL);
 
+	*class_dev_p = NULL;
+
 	if (!fw_priv || !class_dev) {
 		printk(KERN_ERR "%s: kmalloc failed\n", __FUNCTION__);
 		retval = -ENOMEM;
@@ -318,10 +323,11 @@ error_remove_data:
 	sysfs_remove_bin_file(&class_dev->kobj, &fw_priv->attr_data);
 error_unreg_class_dev:
 	class_device_unregister(class_dev);
+	goto out;
+
 error_kfree:
 	kfree(fw_priv);
 	kfree(class_dev);
-	*class_dev_p = NULL;
 out:
 	return retval;
 }
@@ -374,7 +380,6 @@ request_firmware(const struct firmware *
 	wait_for_completion(&fw_priv->completion);
 
 	del_timer_sync(&fw_priv->timeout);
-	fw_remove_class_device(class_dev);
 
 	if (fw_priv->fw->size && !test_bit(FW_STATUS_ABORT, &fw_priv->status)) {
 		*firmware = fw_priv->fw;
@@ -383,7 +388,7 @@ request_firmware(const struct firmware *
 		vfree(fw_priv->fw->data);
 		kfree(fw_priv->fw);
 	}
-	kfree(fw_priv);
+	fw_remove_class_device(class_dev);
 out:
 	return retval;
 }

_