aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/ak4535.c
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2008-08-25 06:49:20 -0400
committerTakashi Iwai <tiwai@suse.de>2008-08-25 07:49:52 -0400
commit3051e41ab7daaa59d4564f20b25dcb8c03f35f2b (patch)
tree0908f13da020b0e6e5d025caa60b1fed4c056abc /sound/soc/codecs/ak4535.c
parentc5d44423d55e3abca7b1d544af9e4c97ec203999 (diff)
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/ak4535.c')
-rw-r--r--sound/soc/codecs/ak4535.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c
index b26003c4f3e8..7da9f467b7b8 100644
--- a/sound/soc/codecs/ak4535.c
+++ b/sound/soc/codecs/ak4535.c
@@ -562,10 +562,9 @@ static int ak4535_codec_probe(struct i2c_adapter *adap, int addr, int kind)
562 client_template.addr = addr; 562 client_template.addr = addr;
563 563
564 i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL); 564 i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
565 if (i2c == NULL) { 565 if (i2c == NULL)
566 kfree(codec);
567 return -ENOMEM; 566 return -ENOMEM;
568 } 567
569 i2c_set_clientdata(i2c, codec); 568 i2c_set_clientdata(i2c, codec);
570 codec->control_data = i2c; 569 codec->control_data = i2c;
571 570
@@ -583,7 +582,6 @@ static int ak4535_codec_probe(struct i2c_adapter *adap, int addr, int kind)
583 return ret; 582 return ret;
584 583
585err: 584err:
586 kfree(codec);
587 kfree(i2c); 585 kfree(i2c);
588 return ret; 586 return ret;
589} 587}
@@ -660,6 +658,11 @@ static int ak4535_probe(struct platform_device *pdev)
660#else 658#else
661 /* Add other interfaces here */ 659 /* Add other interfaces here */
662#endif 660#endif
661
662 if (ret != 0) {
663 kfree(codec->private_data);
664 kfree(codec);
665 }
663 return ret; 666 return ret;
664} 667}
665 668