From: Manuel Estrada Sainz 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; } _