Closed paulhuggett closed 3 months ago
Sorry, I should have included some sample input that exposes the issue rather than just vague warbling… Try:
0x39671FF1, 0x92021008, 0xFFFFFFFF, 0x66BF99A, 0x00000001
This was generated by the fuzzer so is likely nonsensical!
Later… I think there's a similar bug in the sysex8 handling where we have (line #369):
mess.dataLength = (umpMess[0] >> 16) & 0xF
dataLength shouldn't be greater than 13 because we then pass a pointer to an array of 13 bytes to the callback function. A simple fix would be std::min().
I also think that the conditions in lines #373 to #385 should be using >= rather than >. i.e.
if(mess.dataLength > 1)sysex[0] = umpMess[0] & 0x7F;
if(mess.dataLength > 2)sysex[1] = (umpMess[1] >> 24) & 0x7F;
…
should be:
if(mess.dataLength >= 1)sysex[0] = umpMess[0] & 0x7F;
if(mess.dataLength >= 2)sysex[1] = (umpMess[1] >> 24) & 0x7F;
…
This means that a dataLength of 1 extracts from umpMess[0], a dataLength of 2 from umpMess[1], and so on.
Actually, there's another tweak necessary here because the sysex8 bytes are each 8-bits so the mask should be 0xFF (not 0x7F):
if(mess.dataLength >= 1)sysex[0] = umpMess[0] & 0xFF;
if(mess.dataLength >= 2)sysex[1] = (umpMess[1] >> 24) & 0xFF;
…
@paulhuggett Thanks for these - I have updated the code as you suggested :)
I'm sure that you're probably sick of hearing from me by now… just let me know if you'd like me to stop!
umpProcessor.cpp contains the following code:
This sets
mess.dataLength
from the 4 bits extracted from the 32-bit UMP packet — the ”#of bytes” field — and setsmess.data
to point to a 6 byte stack-allocated array. Unfortunately, this 4-bit field could contain any value up to 15. Bad input data where the field contains a value > 6 could cause the sendOutSysEx() callback to read beyond the end of themess.data
buffer.My suggested fix is simply to clamp the value of dataLength:
(Discovered when building some fuzz tests for umpProcessor.)