diff options
author | Takashi Iwai <tiwai@suse.de> | 2006-03-21 16:07:13 +0100 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2006-03-22 10:43:56 +0100 |
commit | c6077b3000184c7f69c4798b9025e5fbd69c8c62 (patch) | |
tree | 7ba83932972197bc4f2fd2c29cf5448fc34c2d26 /sound | |
parent | c5c079e31cba3e6f93ef098911e216b79d0a84e8 (diff) | |
download | linux-c6077b3000184c7f69c4798b9025e5fbd69c8c62.tar.gz linux-c6077b3000184c7f69c4798b9025e5fbd69c8c62.tar.bz2 linux-c6077b3000184c7f69c4798b9025e5fbd69c8c62.zip |
[ALSA] Fix memory leaks in error path of control.c
Modules: Control Midlevel
Fix memory leaks in error path of control.c (only with CONFIG_SND_DEBUG=y).
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/core/control.c | 19 |
1 files changed, 12 insertions, 7 deletions
diff --git a/sound/core/control.c b/sound/core/control.c index 9742bdba0de1..574745314e70 100644 --- a/sound/core/control.c +++ b/sound/core/control.c @@ -309,28 +309,29 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol) { struct snd_ctl_elem_id id; unsigned int idx; + int err = -EINVAL; - snd_assert(card != NULL, return -EINVAL); if (! kcontrol) - return -EINVAL; - snd_assert(kcontrol->info != NULL, return -EINVAL); + return err; + snd_assert(card != NULL, goto error); + snd_assert(kcontrol->info != NULL, goto error); id = kcontrol->id; down_write(&card->controls_rwsem); if (snd_ctl_find_id(card, &id)) { up_write(&card->controls_rwsem); - snd_ctl_free_one(kcontrol); snd_printd(KERN_ERR "control %i:%i:%i:%s:%i is already present\n", id.iface, id.device, id.subdevice, id.name, id.index); - return -EBUSY; + err = -EBUSY; + goto error; } if (snd_ctl_find_hole(card, kcontrol->count) < 0) { up_write(&card->controls_rwsem); - snd_ctl_free_one(kcontrol); - return -ENOMEM; + err = -ENOMEM; + goto error; } list_add_tail(&kcontrol->list, &card->controls); card->controls_count += kcontrol->count; @@ -340,6 +341,10 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol) for (idx = 0; idx < kcontrol->count; idx++, id.index++, id.numid++) snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id); return 0; + + error: + snd_ctl_free_one(kcontrol); + return err; } /** |