aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2018-03-10 17:04:23 -0500
committerTakashi Iwai <tiwai@suse.de>2018-03-11 05:25:10 -0400
commit01c0b4265cc16bc1f43f475c5944c55c10d5768f (patch)
tree1b6bcb6a25c2c4d73eb9f3247f63c84216f6a9bb
parenta2ff19f7b70118ced291a28d5313469914de451b (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.c10
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
1779static int snd_pcm_oss_set_format(struct snd_pcm_oss_file *pcm_oss_file, int format) 1781static int snd_pcm_oss_set_format(struct snd_pcm_oss_file *pcm_oss_file, int format)