History

ALSA: rawmidi: Fix missing input substream checks in compat ioctls

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.

Takashi Iwai committed 8 years ago

Commit 8a56ef41 parent a3dafb21 file · +12 −6Browse files

Unified · Split

sound/core/rawmidi_compat.c+12−6
@@ -36,8 +36,6 @@ static int snd_rawmidi_ioctl_params_compat(struct snd_rawmidi_file *rfile, · 35 unmodified lines
36 struct snd_rawmidi_params params;36 struct snd_rawmidi_params params;
37 unsigned int val;37 unsigned int val;
38 38
39 if (rfile->output == NULL)
40 return -EINVAL;
41 if (get_user(params.stream, &src->stream) ||39 if (get_user(params.stream, &src->stream) ||
42 get_user(params.buffer_size, &src->buffer_size) ||40 get_user(params.buffer_size, &src->buffer_size) ||
43 get_user(params.avail_min, &src->avail_min) ||41 get_user(params.avail_min, &src->avail_min) ||
@@ -46,8 +44,12 @@ static int snd_rawmidi_ioctl_params_compat(struct snd_rawmidi_file *rfile, · 2 unmodified lines
46 params.no_active_sensing = val;44 params.no_active_sensing = val;
47 switch (params.stream) {45 switch (params.stream) {
48 case SNDRV_RAWMIDI_STREAM_OUTPUT:46 case SNDRV_RAWMIDI_STREAM_OUTPUT:
47 if (!rfile->output)
48 return -EINVAL;
49 return snd_rawmidi_output_params(rfile->output, &params);49 return snd_rawmidi_output_params(rfile->output, &params);
50 case SNDRV_RAWMIDI_STREAM_INPUT:50 case SNDRV_RAWMIDI_STREAM_INPUT:
51 if (!rfile->input)
52 return -EINVAL;
51 return snd_rawmidi_input_params(rfile->input, &params);53 return snd_rawmidi_input_params(rfile->input, &params);
52 }54 }
53 return -EINVAL;55 return -EINVAL;
@@ -67,16 +69,18 @@ static int snd_rawmidi_ioctl_status_compat(struct snd_rawmidi_file *rfile, · 13 unmodified lines
67 int err;69 int err;
68 struct snd_rawmidi_status status;70 struct snd_rawmidi_status status;
69 71
70 if (rfile->output == NULL)
71 return -EINVAL;
72 if (get_user(status.stream, &src->stream))72 if (get_user(status.stream, &src->stream))
73 return -EFAULT;73 return -EFAULT;
74 74
75 switch (status.stream) {75 switch (status.stream) {
76 case SNDRV_RAWMIDI_STREAM_OUTPUT:76 case SNDRV_RAWMIDI_STREAM_OUTPUT:
77 if (!rfile->output)
78 return -EINVAL;
77 err = snd_rawmidi_output_status(rfile->output, &status);79 err = snd_rawmidi_output_status(rfile->output, &status);
78 break;80 break;
79 case SNDRV_RAWMIDI_STREAM_INPUT:81 case SNDRV_RAWMIDI_STREAM_INPUT:
82 if (!rfile->input)
83 return -EINVAL;
80 err = snd_rawmidi_input_status(rfile->input, &status);84 err = snd_rawmidi_input_status(rfile->input, &status);
81 break;85 break;
82 default:86 default:
@@ -112,16 +116,18 @@ static int snd_rawmidi_ioctl_status_x32(struct snd_rawmidi_file *rfile, · 29 unmodified lines
112 int err;116 int err;
113 struct snd_rawmidi_status status;117 struct snd_rawmidi_status status;
114 118
115 if (rfile->output == NULL)
116 return -EINVAL;
117 if (get_user(status.stream, &src->stream))119 if (get_user(status.stream, &src->stream))
118 return -EFAULT;120 return -EFAULT;
119 121
120 switch (status.stream) {122 switch (status.stream) {
121 case SNDRV_RAWMIDI_STREAM_OUTPUT:123 case SNDRV_RAWMIDI_STREAM_OUTPUT:
124 if (!rfile->output)
125 return -EINVAL;
122 err = snd_rawmidi_output_status(rfile->output, &status);126 err = snd_rawmidi_output_status(rfile->output, &status);
123 break;127 break;
124 case SNDRV_RAWMIDI_STREAM_INPUT:128 case SNDRV_RAWMIDI_STREAM_INPUT:
129 if (!rfile->input)
130 return -EINVAL;
125 err = snd_rawmidi_input_status(rfile->input, &status);131 err = snd_rawmidi_input_status(rfile->input, &status);
126 break;132 break;
127 default:133 default: