RspConnector::DecodeRLE does not bounds check the '*' run-length branch:
else if (data.m_data[index] == '*')
{
auto repeat = data.m_data[index + 1] - 29; // index + 1 may be past the end
auto last_char = result[result.size() - 1]; // result may be empty -> result[SIZE_MAX]
An RLE run is <char>*<count>, so it needs both a count byte after the * and a
character before it to repeat. Neither is checked.
- A packet whose first byte is
* leaves result empty, so result[result.size() - 1]
indexes SIZE_MAX. ASan reports stack-buffer-overflow ... underflows this variable 'result'. DecodeRLE(RspData("*A")) and DecodeRLE(RspData("*")) both abort.
- A trailing
* reads m_data[index + 1] one past the buffer. DataBuffer::operator[]
is unchecked. ASan does not flag this one because the buffer comes from BN core, which
is not instrumented, so this part is from reading the code rather than a tool result.
This is reachable from ordinary traffic: RLE is a standard RSP feature and gdbserver uses
it to compress repeated bytes, which is common when reading module maps or zero-filled
memory. The data is entirely stub controlled.
Found by fuzzing the GDB adapter against a live Corellium stub through a mutating proxy.
The path hit was GetModuleList -> GetRemoteFile -> HostFileIO -> ReceiveRspData -> DecodeRLE.
Distinct from #1164: that is unhandled exceptions from integer parsing, and #1166 does not
touch DecodeRLE. This one is memory corruption, so a catch boundary does not help it.
RspConnector::DecodeRLEdoes not bounds check the'*'run-length branch:An RLE run is
<char>*<count>, so it needs both a count byte after the*and acharacter before it to repeat. Neither is checked.
*leavesresultempty, soresult[result.size() - 1]indexes
SIZE_MAX. ASan reportsstack-buffer-overflow ... underflows this variable 'result'.DecodeRLE(RspData("*A"))andDecodeRLE(RspData("*"))both abort.*readsm_data[index + 1]one past the buffer.DataBuffer::operator[]is unchecked. ASan does not flag this one because the buffer comes from BN core, which
is not instrumented, so this part is from reading the code rather than a tool result.
This is reachable from ordinary traffic: RLE is a standard RSP feature and gdbserver uses
it to compress repeated bytes, which is common when reading module maps or zero-filled
memory. The data is entirely stub controlled.
Found by fuzzing the GDB adapter against a live Corellium stub through a mutating proxy.
The path hit was
GetModuleList -> GetRemoteFile -> HostFileIO -> ReceiveRspData -> DecodeRLE.Distinct from #1164: that is unhandled exceptions from integer parsing, and #1166 does not
touch
DecodeRLE. This one is memory corruption, so a catch boundary does not help it.