Commit b4f939a2 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] request_firmware(): fix firmware_priv leak

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

Based on patch and suggestions from Dmitry Torokhov

- release 'struct firmware_priv' from class_dev->release.
parent fbe910e4
...@@ -232,6 +232,9 @@ static struct bin_attribute firmware_attr_data_tmpl = { ...@@ -232,6 +232,9 @@ static struct bin_attribute firmware_attr_data_tmpl = {
static void static void
fw_class_dev_release(struct class_device *class_dev) 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); kfree(class_dev);
} }
...@@ -258,6 +261,8 @@ fw_setup_class_device(struct class_device **class_dev_p, ...@@ -258,6 +261,8 @@ fw_setup_class_device(struct class_device **class_dev_p,
struct class_device *class_dev = kmalloc(sizeof (struct class_device), struct class_device *class_dev = kmalloc(sizeof (struct class_device),
GFP_KERNEL); GFP_KERNEL);
*class_dev_p = NULL;
if (!fw_priv || !class_dev) { if (!fw_priv || !class_dev) {
printk(KERN_ERR "%s: kmalloc failed\n", __FUNCTION__); printk(KERN_ERR "%s: kmalloc failed\n", __FUNCTION__);
retval = -ENOMEM; retval = -ENOMEM;
...@@ -318,10 +323,11 @@ fw_setup_class_device(struct class_device **class_dev_p, ...@@ -318,10 +323,11 @@ fw_setup_class_device(struct class_device **class_dev_p,
sysfs_remove_bin_file(&class_dev->kobj, &fw_priv->attr_data); sysfs_remove_bin_file(&class_dev->kobj, &fw_priv->attr_data);
error_unreg_class_dev: error_unreg_class_dev:
class_device_unregister(class_dev); class_device_unregister(class_dev);
goto out;
error_kfree: error_kfree:
kfree(fw_priv); kfree(fw_priv);
kfree(class_dev); kfree(class_dev);
*class_dev_p = NULL;
out: out:
return retval; return retval;
} }
...@@ -374,7 +380,6 @@ request_firmware(const struct firmware **firmware, const char *name, ...@@ -374,7 +380,6 @@ request_firmware(const struct firmware **firmware, const char *name,
wait_for_completion(&fw_priv->completion); wait_for_completion(&fw_priv->completion);
del_timer_sync(&fw_priv->timeout); 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)) { if (fw_priv->fw->size && !test_bit(FW_STATUS_ABORT, &fw_priv->status)) {
*firmware = fw_priv->fw; *firmware = fw_priv->fw;
...@@ -383,7 +388,7 @@ request_firmware(const struct firmware **firmware, const char *name, ...@@ -383,7 +388,7 @@ request_firmware(const struct firmware **firmware, const char *name,
vfree(fw_priv->fw->data); vfree(fw_priv->fw->data);
kfree(fw_priv->fw); kfree(fw_priv->fw);
} }
kfree(fw_priv); fw_remove_class_device(class_dev);
out: out:
return retval; return retval;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment