diff options
author | Jean Delvare <khali@linux-fr.org> | 2008-08-25 14:49:20 +0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2008-08-25 15:49:52 +0400 |
commit | 3051e41ab7daaa59d4564f20b25dcb8c03f35f2b (patch) | |
tree | 0908f13da020b0e6e5d025caa60b1fed4c056abc /sound/soc/codecs/uda1380.c | |
parent | c5d44423d55e3abca7b1d544af9e4c97ec203999 (diff) | |
download | linux-3051e41ab7daaa59d4564f20b25dcb8c03f35f2b.tar.xz |
ALSA: ASoC: Fix double free and memory leak in many codec drivers
Many SoC audio codec drivers have improper freeing of memory in error
paths.
* codec is allocated in the platform device probe function, but is not
freed there in case of error. Instead it is freed in the i2c device
probe function's error path. However the success or failure of both
functions is not linked, so this could result in a double free (if
the platform device is successfully probed, the i2c device probing
fails and then the platform driver is unregistered.)
* codec->private_data is allocated in many platform device probe
functions but not freed in their error paths.
This patch hopefully solves all these problems.
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/soc/codecs/uda1380.c')
-rw-r--r-- | sound/soc/codecs/uda1380.c | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c index a52d6d9e007a..807318fbdc8f 100644 --- a/sound/soc/codecs/uda1380.c +++ b/sound/soc/codecs/uda1380.c @@ -729,10 +729,9 @@ static int uda1380_codec_probe(struct i2c_adapter *adap, int addr, int kind) client_template.addr = addr; i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL); - if (i2c == NULL) { - kfree(codec); + if (i2c == NULL) return -ENOMEM; - } + i2c_set_clientdata(i2c, codec); codec->control_data = i2c; @@ -750,7 +749,6 @@ static int uda1380_codec_probe(struct i2c_adapter *adap, int addr, int kind) return ret; err: - kfree(codec); kfree(i2c); return ret; } @@ -817,6 +815,9 @@ static int uda1380_probe(struct platform_device *pdev) #else /* Add other interfaces here */ #endif + + if (ret != 0) + kfree(codec); return ret; } |