plumb: bound 9P message size in recvMsg to fix SIGBUS on desync
A corrupt or desynced stream could deliver a size[4] far larger than the negotiated msize. recvMsg trusted it, so bodyLen=int(size)-7 became huge (or negative when size>INT_MAX), and the following b.resize()/readExactly corrupted the heap -> SIGBUS in the PlumbReader edit-port thread. Reject any message whose size exceeds the negotiated msize.
This commit is contained in:
parent
f503c53dfc
commit
08a75c06af
|
|
@ -184,6 +184,15 @@ bool NineP::recvMsg(uint8_t *type, uint16_t *tag, QByteArray *body)
|
|||
m_error = QStringLiteral("9P message too short (%1)").arg(size);
|
||||
return false;
|
||||
}
|
||||
// The negotiated msize is the hard ceiling for any single 9P message. A
|
||||
// larger size[4] means a desynced or corrupt stream; trusting it would make
|
||||
// the b.resize()/readExactly() below allocate and write a bogus (possibly
|
||||
// multi-gigabyte, or negative-when-cast-to-int) buffer, corrupting the heap.
|
||||
// Reject it instead of crashing.
|
||||
if (size > m_msize) {
|
||||
m_error = QStringLiteral("9P message too large (%1 > msize %2)").arg(size).arg(m_msize);
|
||||
return false;
|
||||
}
|
||||
*type = uint8_t(hdr[4]);
|
||||
*tag = uint16_t(uint8_t(hdr[5]) | (uint16_t(uint8_t(hdr[6])) << 8));
|
||||
const int bodyLen = int(size) - 7;
|
||||
|
|
|
|||
Loading…
Reference in New Issue