Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+6 -4
+6 -4
sound/core/oss/pcm_oss.c
··· 1762 1762 return -ENOMEM; 1763 1763 _snd_pcm_hw_params_any(params); 1764 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 1765 if (err < 0) 1768 - return err; 1766 + goto error; 1767 + format_mask = hw_param_mask_c(params, SNDRV_PCM_HW_PARAM_FORMAT); 1769 1768 for (fmt = 0; fmt < 32; ++fmt) { 1770 1769 if (snd_mask_test(format_mask, fmt)) { 1771 1770 int f = snd_pcm_oss_format_to(fmt); ··· 1772 1773 formats |= f; 1773 1774 } 1774 1775 } 1775 - return formats; 1776 + 1777 + error: 1778 + kfree(params); 1779 + return err < 0 ? err : formats; 1776 1780 } 1777 1781 1778 1782 static int snd_pcm_oss_set_format(struct snd_pcm_oss_file *pcm_oss_file, int format)