diff --git a/src/plumb/ninep.cpp b/src/plumb/ninep.cpp index abbbcda..163ed1a 100644 --- a/src/plumb/ninep.cpp +++ b/src/plumb/ninep.cpp @@ -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;