ALSA: seq_midi_emul: small array underflow
Subsystems (2)
PATCH 1/1 ALSA: seq_midi_emul: small array underflow
In snd_opl3_calc_pitch() then the limit is:
if (pitchbend > 0x1FFF) pitchbend = 0x1FFF;
But it can underflow meaning that segment can be as low as SHORT_MIN / 0x1000 and we can read 6 elements before the start of the opl3_note_table[] array.
include/sound/seq_midi_emul.h +1 -1
@@ -44,7 +44,7 @@ struct snd_midi_channel {unsigned char midi_aftertouch;/* Aftertouch (key pressure) */ unsigned char midi_pressure;/* Channel pressure */ unsigned char midi_program;/* Instrument number */ -short midi_pitchbend;/* Pitch bend amount */ +unsigned short midi_pitchbend;/* Pitch bend amount */ unsigned char control[128 ];/* Current value of all controls */ unsigned char note[128 ];/* Current status for all notes */
include/sound/seq_midi_emul.h struct snd_midi_channel { · line 47
Quoted 11 lines · Dan Carpenter
In
snd_opl3_calc_pitch()then the limit is:if (pitchbend > 0x1FFF) pitchbend = 0x1FFF;But it can underflow meaning that segment can be as low as
SHORT_MIN/0x1000and we can read 6 elements before the start of the opl3_note_table[] array.include/sound/seq_midi_emul.h +1
-1-short midi_pitchbend;/* Pitch bend amount */ +unsigned short midi_pitchbend;/* Pitch bend amount */
Pitch bend is a signed 14-bit value. What is wrong is the missing check for the lower bound.
Regards,
Clemens
Quoted 10 lines · Clemens Ladisch
Quoted 8 lines · Dan Carpenter
In
snd_opl3_calc_pitch()then the limit is:if (pitchbend > 0x1FFF) pitchbend = 0x1FFF;But it can underflow meaning that segment can be as low as
SHORT_MIN/0x1000and we can read 6 elements before the start of the opl3_note_table[] array.
Quoted 6 lines
include/sound/seq_midi_emul.h struct snd_midi_channel { · line 47
Quoted 2 lines
include/sound/seq_midi_emul.h +1
-1-short midi_pitchbend;/* Pitch bend amount */ +unsigned short midi_pitchbend;/* Pitch bend amount */ Pitch bend is a signed 14-bit value. What is wrong is the missing check for the lower bound.
Thanks for the review. I will resend.
regards,
dan carpenter
PATCH v2 1/1 ALSA: opl3: small array underflow
In reply to Clemens LadischWe don't check for negatives so "pitchbend" can be SHRT_MIN here. It means that we can read up to 6 elements before the start of the opl3_note_table[] array.
There are several ways we could fix this. I have gone with what is maybe the lazier approach of just changing negative values to zero. Hopefully, people aren't passing negatives here anyway.
---
v2: The first patch just chan->midi_pitchbend unsigned but Clemens Ladisch pointed out that that breaks the API.
sound/drivers/opl3/opl3_midi.c +2 -0
@@ -105,6 +105,8 @@ static void snd_opl3_calc_pitch(unsigned char *fnum, unsigned char *blocknum,int pitchbend = chan->midi_pitchbend;int segment; +if (pitchbend <0 ) + pitchbend =0 ;if (pitchbend >0x1FFF ) pitchbend =0x1FFF ;
Re: [alsa-devel] [patch v2] ALSA: opl3: small array underflow
Quoted 6 lines · Dan Carpenter
We don't check for negatives so "pitchbend" can be
SHRT_MINhere. It means that we can read up to 6 elements before the start of the opl3_note_table[] array.There are several ways we could fix this. I have gone with what is maybe the lazier approach of just changing negative values to zero.
The lower bound is not zero but -8192.
Regards,
Clemens
Re: [alsa-devel] [patch v2] ALSA: opl3: small array underflow
Quoted 9 lines · Clemens Ladisch
Quoted 6 lines · Dan Carpenter
We don't check for negatives so "pitchbend" can be
SHRT_MINhere. It means that we can read up to 6 elements before the start of the opl3_note_table[] array.There are several ways we could fix this. I have gone with what is maybe the lazier approach of just changing negative values to zero.
The lower bound is not zero but -8192.
Oh. I should have understood that from your previous email. Sorry for that. Third time is lucky, I suppose.
regards,
dan carpenter