seq_oss_event: missing range checks
Subsystems (2)
PATCH 1/1 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()sound/core/seq/oss/seq_oss_event.c +12 -2
@@ -285,7 +285,12 @@ local_event(struct seq_oss_devinfo *dp, union evrec *q, struct snd_seq_event *evstatic int note_on_event (struct seq_oss_devinfo *dp,int dev,int ch,int note,int vel,struct snd_seq_event *ev) { -struct seq_oss_synthinfo *info = &dp->synths[dev]; +struct seq_oss_synthinfo *info; + +if (!snd_seq_oss_synth_is_valid (dp, dev)) +return -ENXIO ; + + info = &dp->synths[dev];switch (info->arg.event_passing) {case SNDRV_SEQ_OSS_PROCESS_EVENTS :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, ststatic int note_off_event (struct seq_oss_devinfo *dp,int dev,int ch,int note,int vel,struct snd_seq_event *ev) { -struct seq_oss_synthinfo *info = &dp->synths[dev]; +struct seq_oss_synthinfo *info; + +if (!snd_seq_oss_synth_is_valid (dp, dev)) +return -ENXIO ; + + info = &dp->synths[dev];switch (info->arg.event_passing) {case SNDRV_SEQ_OSS_PROCESS_EVENTS :if (! info->ch || ch <0 || ch >= info->nr_voices) {
Takashi Iwai
AppliedAt Mon, 4 Mar 2013 15:19:18 +0300,
Quoted 8 lines · Dan Carpenter
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 insideset_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.
Quoted 7 lines
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 <[email protected]>
Thanks, applied.
Takashi
Quoted 38 lines
sound/core/seq/oss/seq_oss_event.c +12
-2@@ -285,7 +285,12 @@ local_event(struct seq_oss_devinfo *dp, union evrec *q, struct snd_seq_event *evstatic int note_on_event (struct seq_oss_devinfo *dp,int dev,int ch,int note,int vel,struct snd_seq_event *ev) { -struct seq_oss_synthinfo *info = &dp->synths[dev]; +struct seq_oss_synthinfo *info; + +if (!snd_seq_oss_synth_is_valid (dp, dev)) +return -ENXIO ; + + info = &dp->synths[dev];switch (info->arg.event_passing) {case SNDRV_SEQ_OSS_PROCESS_EVENTS :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, ststatic int note_off_event (struct seq_oss_devinfo *dp,int dev,int ch,int note,int vel,struct snd_seq_event *ev) { -struct seq_oss_synthinfo *info = &dp->synths[dev]; +struct seq_oss_synthinfo *info; + +if (!snd_seq_oss_synth_is_valid (dp, dev)) +return -ENXIO ; + + info = &dp->synths[dev];switch (info->arg.event_passing) {case SNDRV_SEQ_OSS_PROCESS_EVENTS :if (! info->ch || ch <0 || ch >= info->nr_voices) {_______________________________________________
Alsa-devel mailing list
[email protected]
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel