diff options
| author | Takashi Iwai <tiwai@suse.de> | 2018-03-10 23:04:23 +0100 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-03-21 12:05:43 +0100 |
| commit | eb0e7a1f56870d9865e8cf70db1f80ec2e3350bd (patch) | |
| tree | 4705e699b0126069e1f9cebc721bbd0bb31cae02 | |
| parent | bf724633cfda3a01001b5efe0fc49df2d6f91b9d (diff) | |
| download | linux-eb0e7a1f56870d9865e8cf70db1f80ec2e3350bd.tar.gz linux-eb0e7a1f56870d9865e8cf70db1f80ec2e3350bd.tar.bz2 linux-eb0e7a1f56870d9865e8cf70db1f80ec2e3350bd.zip | |
ALSA: pcm: Fix UAF in snd_pcm_oss_get_formats()
commit 01c0b4265cc16bc1f43f475c5944c55c10d5768f upstream.
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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
| -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 c2db7e905f7d..012881461058 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) return -ENOMEM; _snd_pcm_hw_params_any(params); err = snd_pcm_hw_refine(substream, params); - format_mask = hw_param_mask_c(params, SNDRV_PCM_HW_PARAM_FORMAT); - kfree(params); if (err < 0) - return err; + goto error; + format_mask = hw_param_mask_c(params, SNDRV_PCM_HW_PARAM_FORMAT); for (fmt = 0; fmt < 32; ++fmt) { if (snd_mask_test(format_mask, fmt)) { 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) formats |= f; } } - return formats; + + error: + kfree(params); + return err < 0 ? err : formats; } static int snd_pcm_oss_set_format(struct snd_pcm_oss_file *pcm_oss_file, int format) |
