| From: Takashi Iwai <tiwai@suse.de> |
| Date: Thu, 19 Apr 2018 18:16:15 +0200 |
| Subject: ALSA: rawmidi: Fix missing input substream checks in compat ioctls |
| |
| commit 8a56ef4f3ffba9ebf4967b61ef600b0a7ba10f11 upstream. |
| |
| Some rawmidi compat ioctls lack of the input substream checks |
| (although they do check only for rfile->output). This many eventually |
| lead to an Oops as NULL substream is passed to the rawmidi core |
| functions. |
| |
| Fix it by adding the proper checks before each function call. |
| |
| The bug was spotted by syzkaller. |
| |
| Reported-by: syzbot+f7a0348affc3b67bc617@syzkaller.appspotmail.com |
| Signed-off-by: Takashi Iwai <tiwai@suse.de> |
| Signed-off-by: Ben Hutchings <ben@decadent.org.uk> |
| --- |
| sound/core/rawmidi_compat.c | 18 ++++++++++++------ |
| 1 file changed, 12 insertions(+), 6 deletions(-) |
| |
| --- a/sound/core/rawmidi_compat.c |
| +++ b/sound/core/rawmidi_compat.c |
| @@ -36,8 +36,6 @@ static int snd_rawmidi_ioctl_params_comp |
| struct snd_rawmidi_params params; |
| unsigned int val; |
| |
| - if (rfile->output == NULL) |
| - return -EINVAL; |
| if (get_user(params.stream, &src->stream) || |
| get_user(params.buffer_size, &src->buffer_size) || |
| get_user(params.avail_min, &src->avail_min) || |
| @@ -46,8 +44,12 @@ static int snd_rawmidi_ioctl_params_comp |
| params.no_active_sensing = val; |
| switch (params.stream) { |
| case SNDRV_RAWMIDI_STREAM_OUTPUT: |
| + if (!rfile->output) |
| + return -EINVAL; |
| return snd_rawmidi_output_params(rfile->output, ¶ms); |
| case SNDRV_RAWMIDI_STREAM_INPUT: |
| + if (!rfile->input) |
| + return -EINVAL; |
| return snd_rawmidi_input_params(rfile->input, ¶ms); |
| } |
| return -EINVAL; |
| @@ -67,16 +69,18 @@ static int snd_rawmidi_ioctl_status_comp |
| int err; |
| struct snd_rawmidi_status status; |
| |
| - if (rfile->output == NULL) |
| - return -EINVAL; |
| if (get_user(status.stream, &src->stream)) |
| return -EFAULT; |
| |
| switch (status.stream) { |
| case SNDRV_RAWMIDI_STREAM_OUTPUT: |
| + if (!rfile->output) |
| + return -EINVAL; |
| err = snd_rawmidi_output_status(rfile->output, &status); |
| break; |
| case SNDRV_RAWMIDI_STREAM_INPUT: |
| + if (!rfile->input) |
| + return -EINVAL; |
| err = snd_rawmidi_input_status(rfile->input, &status); |
| break; |
| default: |
| @@ -113,16 +117,18 @@ static int snd_rawmidi_ioctl_status_x32( |
| int err; |
| struct snd_rawmidi_status status; |
| |
| - if (rfile->output == NULL) |
| - return -EINVAL; |
| if (get_user(status.stream, &src->stream)) |
| return -EFAULT; |
| |
| switch (status.stream) { |
| case SNDRV_RAWMIDI_STREAM_OUTPUT: |
| + if (!rfile->output) |
| + return -EINVAL; |
| err = snd_rawmidi_output_status(rfile->output, &status); |
| break; |
| case SNDRV_RAWMIDI_STREAM_INPUT: |
| + if (!rfile->input) |
| + return -EINVAL; |
| err = snd_rawmidi_input_status(rfile->input, &status); |
| break; |
| default: |