diff options
author | Takashi Iwai <tiwai@suse.de> | 2018-03-10 17:04:23 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2018-03-11 05:25:10 -0400 |
commit | 01c0b4265cc16bc1f43f475c5944c55c10d5768f (patch) | |
tree | 1b6bcb6a25c2c4d73eb9f3247f63c84216f6a9bb | |
parent | a2ff19f7b70118ced291a28d5313469914de451b (diff) |
ALSA: pcm: Fix UAF in snd_pcm_oss_get_formats()
snd_pcm_oss_get_formats() has an obvious use-after-free around
snd_mask_test() calls, as spotted by syzbot. The passed format_mask
argument is a pointer to the hw_params object that is freed before the
loop. What a surprise that it has been present since the original
code of decades ago...
Reported-by: syzbot+4090700a4f13fccaf648@syzkaller.appspotmail.com
Cc: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r-- | sound/core/oss/pcm_oss.c | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c index b044c0a5a674..02298c9c6020 100644 --- a/sound/core/oss/pcm_oss.c +++ b/sound/core/oss/pcm_oss.c | |||
@@ -1762,10 +1762,9 @@ static int snd_pcm_oss_get_formats(struct snd_pcm_oss_file *pcm_oss_file) | |||
1762 | return -ENOMEM; | 1762 | return -ENOMEM; |
1763 | _snd_pcm_hw_params_any(params); | 1763 | _snd_pcm_hw_params_any(params); |
1764 | err = snd_pcm_hw_refine(substream, params); | 1764 | err = snd_pcm_hw_refine(substream, params); |
1765 | format_mask = hw_param_mask_c(params, SNDRV_PCM_HW_PARAM_FORMAT); | ||
1766 | kfree(params); | ||
1767 | if (err < 0) | 1765 | if (err < 0) |
1768 | return err; | 1766 | goto error; |
1767 | format_mask = hw_param_mask_c(params, SNDRV_PCM_HW_PARAM_FORMAT); | ||
1769 | for (fmt = 0; fmt < 32; ++fmt) { | 1768 | for (fmt = 0; fmt < 32; ++fmt) { |
1770 | if (snd_mask_test(format_mask, fmt)) { | 1769 | if (snd_mask_test(format_mask, fmt)) { |
1771 | int f = snd_pcm_oss_format_to(fmt); | 1770 | int f = snd_pcm_oss_format_to(fmt); |
@@ -1773,7 +1772,10 @@ static int snd_pcm_oss_get_formats(struct snd_pcm_oss_file *pcm_oss_file) | |||
1773 | formats |= f; | 1772 | formats |= f; |
1774 | } | 1773 | } |
1775 | } | 1774 | } |
1776 | return formats; | 1775 | |
1776 | error: | ||
1777 | kfree(params); | ||
1778 | return err < 0 ? err : formats; | ||
1777 | } | 1779 | } |
1778 | 1780 | ||
1779 | static int snd_pcm_oss_set_format(struct snd_pcm_oss_file *pcm_oss_file, int format) | 1781 | static int snd_pcm_oss_set_format(struct snd_pcm_oss_file *pcm_oss_file, int format) |