diff options
author | Wenwen Wang <wenwen@cs.uga.edu> | 2019-08-07 05:08:51 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2019-08-07 06:20:00 -0400 |
commit | 3d92aa45fbfd7319e3a19f4ec59fd32b3862b723 (patch) | |
tree | a185bad2ee4923bb7ec865bd78d4fa032ade10f3 | |
parent | c1c6c877b0c79fd7e05c931435aa42211eaeebaf (diff) |
ALSA: hiface: fix multiple memory leak bugs
In hiface_pcm_init(), 'rt' is firstly allocated through kzalloc(). Later
on, hiface_pcm_init_urb() is invoked to initialize 'rt->out_urbs[i]'. In
hiface_pcm_init_urb(), 'rt->out_urbs[i].buffer' is allocated through
kzalloc(). However, if hiface_pcm_init_urb() fails, both 'rt' and
'rt->out_urbs[i].buffer' are not deallocated, leading to memory leak bugs.
Also, 'rt->out_urbs[i].buffer' is not deallocated if snd_pcm_new() fails.
To fix the above issues, free 'rt' and 'rt->out_urbs[i].buffer'.
Fixes: a91c3fb2f842 ("Add M2Tech hiFace USB-SPDIF driver")
Signed-off-by: Wenwen Wang <wenwen@cs.uga.edu>
Cc: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r-- | sound/usb/hiface/pcm.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/sound/usb/hiface/pcm.c b/sound/usb/hiface/pcm.c index 14fc1e1d5d13..c406497c5919 100644 --- a/sound/usb/hiface/pcm.c +++ b/sound/usb/hiface/pcm.c | |||
@@ -600,14 +600,13 @@ int hiface_pcm_init(struct hiface_chip *chip, u8 extra_freq) | |||
600 | ret = hiface_pcm_init_urb(&rt->out_urbs[i], chip, OUT_EP, | 600 | ret = hiface_pcm_init_urb(&rt->out_urbs[i], chip, OUT_EP, |
601 | hiface_pcm_out_urb_handler); | 601 | hiface_pcm_out_urb_handler); |
602 | if (ret < 0) | 602 | if (ret < 0) |
603 | return ret; | 603 | goto error; |
604 | } | 604 | } |
605 | 605 | ||
606 | ret = snd_pcm_new(chip->card, "USB-SPDIF Audio", 0, 1, 0, &pcm); | 606 | ret = snd_pcm_new(chip->card, "USB-SPDIF Audio", 0, 1, 0, &pcm); |
607 | if (ret < 0) { | 607 | if (ret < 0) { |
608 | kfree(rt); | ||
609 | dev_err(&chip->dev->dev, "Cannot create pcm instance\n"); | 608 | dev_err(&chip->dev->dev, "Cannot create pcm instance\n"); |
610 | return ret; | 609 | goto error; |
611 | } | 610 | } |
612 | 611 | ||
613 | pcm->private_data = rt; | 612 | pcm->private_data = rt; |
@@ -620,4 +619,10 @@ int hiface_pcm_init(struct hiface_chip *chip, u8 extra_freq) | |||
620 | 619 | ||
621 | chip->pcm = rt; | 620 | chip->pcm = rt; |
622 | return 0; | 621 | return 0; |
622 | |||
623 | error: | ||
624 | for (i = 0; i < PCM_N_URBS; i++) | ||
625 | kfree(rt->out_urbs[i].buffer); | ||
626 | kfree(rt); | ||
627 | return ret; | ||
623 | } | 628 | } |