diff options
author | Dan Carpenter <dan.carpenter@oracle.com> | 2013-03-04 07:19:18 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2013-03-04 10:39:50 -0500 |
commit | 85c50a5899b23f4f893b0898b286023157b98376 (patch) | |
tree | 4b47c49fc31685ca10b7f48ed6a75b64703b7694 /sound | |
parent | 6dbe51c251a327e012439c4772097a13df43c5b8 (diff) |
ALSA: seq: seq_oss_event: missing range checks
The "dev" variable could be out of bounds. Calling
snd_seq_oss_synth_is_valid() checks that it is is a valid device
which has been opened. We check this inside set_note_event() so
this function can't succeed without a valid "dev". But we need to
do the check earlier to prevent invalid dereferences and memory
corruption.
One call tree where "dev" could be out of bounds is:
-> snd_seq_oss_oob_user()
-> snd_seq_oss_process_event()
-> extended_event()
-> note_on_event()
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/core/seq/oss/seq_oss_event.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/sound/core/seq/oss/seq_oss_event.c b/sound/core/seq/oss/seq_oss_event.c index 066f5f3e3f4c..c3908862bc8b 100644 --- a/sound/core/seq/oss/seq_oss_event.c +++ b/sound/core/seq/oss/seq_oss_event.c | |||
@@ -285,7 +285,12 @@ local_event(struct seq_oss_devinfo *dp, union evrec *q, struct snd_seq_event *ev | |||
285 | static int | 285 | static int |
286 | note_on_event(struct seq_oss_devinfo *dp, int dev, int ch, int note, int vel, struct snd_seq_event *ev) | 286 | note_on_event(struct seq_oss_devinfo *dp, int dev, int ch, int note, int vel, struct snd_seq_event *ev) |
287 | { | 287 | { |
288 | struct seq_oss_synthinfo *info = &dp->synths[dev]; | 288 | struct seq_oss_synthinfo *info; |
289 | |||
290 | if (!snd_seq_oss_synth_is_valid(dp, dev)) | ||
291 | return -ENXIO; | ||
292 | |||
293 | info = &dp->synths[dev]; | ||
289 | switch (info->arg.event_passing) { | 294 | switch (info->arg.event_passing) { |
290 | case SNDRV_SEQ_OSS_PROCESS_EVENTS: | 295 | case SNDRV_SEQ_OSS_PROCESS_EVENTS: |
291 | if (! info->ch || ch < 0 || ch >= info->nr_voices) { | 296 | if (! info->ch || ch < 0 || ch >= info->nr_voices) { |
@@ -340,7 +345,12 @@ note_on_event(struct seq_oss_devinfo *dp, int dev, int ch, int note, int vel, st | |||
340 | static int | 345 | static int |
341 | note_off_event(struct seq_oss_devinfo *dp, int dev, int ch, int note, int vel, struct snd_seq_event *ev) | 346 | note_off_event(struct seq_oss_devinfo *dp, int dev, int ch, int note, int vel, struct snd_seq_event *ev) |
342 | { | 347 | { |
343 | struct seq_oss_synthinfo *info = &dp->synths[dev]; | 348 | struct seq_oss_synthinfo *info; |
349 | |||
350 | if (!snd_seq_oss_synth_is_valid(dp, dev)) | ||
351 | return -ENXIO; | ||
352 | |||
353 | info = &dp->synths[dev]; | ||
344 | switch (info->arg.event_passing) { | 354 | switch (info->arg.event_passing) { |
345 | case SNDRV_SEQ_OSS_PROCESS_EVENTS: | 355 | case SNDRV_SEQ_OSS_PROCESS_EVENTS: |
346 | if (! info->ch || ch < 0 || ch >= info->nr_voices) { | 356 | if (! info->ch || ch < 0 || ch >= info->nr_voices) { |