Commit 6e92c053e655e865994a582d10bcd3f491c0deaa

Authored by Wiebe Cazemier
1 parent 0586e380

Fix packet parsing bug

When sending many 0xFF, it would overflow.

Found by using afl-fuzz.
Showing 2 changed files with 14 additions and 2 deletions
client.cpp
... ... @@ -310,13 +310,16 @@ bool Client::bufferToMqttPackets(std::vector<MqttPacket> &packetQueueIn, Client_
310 310 // Determine the packet length by decoding the variable length
311 311 int remaining_length_i = 1; // index of 'remaining length' field is one after start.
312 312 uint fixed_header_length = 1;
313   - int multiplier = 1;
314   - uint packet_length = 0;
  313 + size_t multiplier = 1;
  314 + size_t packet_length = 0;
315 315 unsigned char encodedByte = 0;
316 316 do
317 317 {
318 318 fixed_header_length++;
319 319  
  320 + if (fixed_header_length > 5)
  321 + throw ProtocolError("Packet signifies more than 5 bytes in variable length header. Invalid.");
  322 +
320 323 // This happens when you only don't have all the bytes that specify the remaining length.
321 324 if (fixed_header_length > readbuf.usedBytes())
322 325 return false;
... ... @@ -335,6 +338,11 @@ bool Client::bufferToMqttPackets(std::vector<MqttPacket> &packetQueueIn, Client_
335 338 throw ProtocolError("An unauthenticated client sends a packet of 1 MB or bigger? Probably it's just random bytes.");
336 339 }
337 340  
  341 + if (packet_length > ABSOLUTE_MAX_PACKET_SIZE)
  342 + {
  343 + throw ProtocolError("A client sends a packet claiming to be bigger than the maximum MQTT allows.");
  344 + }
  345 +
338 346 if (packet_length <= readbuf.usedBytes())
339 347 {
340 348 MqttPacket packet(readbuf, packet_length, fixed_header_length, sender);
... ...
mqttpacket.cpp
... ... @@ -17,6 +17,7 @@ MqttPacket::MqttPacket(CirBuf &amp;buf, size_t packet_len, size_t fixed_header_lengt
17 17 fixed_header_length(fixed_header_length),
18 18 sender(sender)
19 19 {
  20 + assert(packet_len > 0);
20 21 buf.read(bites.data(), packet_len);
21 22  
22 23 first_byte = bites[0];
... ... @@ -116,6 +117,9 @@ MqttPacket::MqttPacket(const PubAck &amp;pubAck) :
116 117  
117 118 void MqttPacket::handle()
118 119 {
  120 + if (packetType == PacketType::Reserved)
  121 + throw ProtocolError("Packet type 0 specified, which is reserved and invalid.");
  122 +
119 123 if (packetType != PacketType::CONNECT)
120 124 {
121 125 if (!sender->getAuthenticated())
... ...