Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Buffer overflow in publishPacket #122

Closed
pakokol opened this issue Jun 28, 2018 · 9 comments · Fixed by #166
Closed

Buffer overflow in publishPacket #122

pakokol opened this issue Jun 28, 2018 · 9 comments · Fixed by #166
Labels

Comments

@pakokol
Copy link

pakokol commented Jun 28, 2018

The function uint16_t Adafruit_MQTT::publishPacket has buffer overflow if you send a packet that is larger than the MAXBUFFERSIZE (topic len + data len).

// as per http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718040
uint16_t Adafruit_MQTT::publishPacket(uint8_t *packet, const char *topic,
                                     uint8_t *data, uint16_t bLen, uint8_t qos) {
  uint8_t *p = packet;
  uint16_t len=0;

  // calc length of non-header data
  len += 2;               // two bytes to set the topic size
  len += strlen(topic); // topic length
  if(qos > 0) { 
    len += 2; // qos packet id
  }
  len += bLen; // payload length

  // Now you can start generating the packet!
  p[0] = MQTT_CTRL_PUBLISH << 4 | qos << 1;
  p++;

  // fill in packet[1] last
  do {
    uint8_t encodedByte = len % 128;
    len /= 128;
    // if there are more data to encode, set the top bit of this byte
    if ( len > 0 ) {
      encodedByte |= 0x80;
    }
    p[0] = encodedByte;
    p++;
  } while ( len > 0 );

  // topic comes before packet identifier
  p = stringprint(p, topic);

  // add packet identifier. used for checking PUBACK in QOS > 0
  if(qos > 0) {
    p[0] = (packet_id_counter >> 8) & 0xFF;
    p[1] = packet_id_counter & 0xFF;
    p+=2;

    // increment the packet id
    packet_id_counter++;
  }

  memmove(p, data, bLen);
  p+= bLen;
  len = p - packet;
  DEBUG_PRINTLN(F("MQTT publish packet:"));
  DEBUG_PRINTBUFFER(buffer, len);
  return len;
}

As you can see from the code there isn't any check if we already went past the packet size and there fore we write over the boundaries.

@brentru brentru added the bug label Aug 17, 2018
@brentru
Copy link
Member

brentru commented Aug 17, 2018

@pakokol Would you want to implement this? If not, I'll implement it in a new pull request.

@pakokol
Copy link
Author

pakokol commented Sep 26, 2018

@brentru sorry for the late response I didn't got any notification that you answered here on github maybe I have accidentally turned off the notifications. I suppose I could implement this if you prefer me to do it.

@brentru
Copy link
Member

brentru commented Sep 26, 2018

@pakokol No problem, still up for it?

@pakokol
Copy link
Author

pakokol commented Sep 26, 2018

@brentru sure why not. Just tell me how is the policity in fixing bugs. It is my first time to collaborate in a project on github :)

@S2Doc
Copy link

S2Doc commented Aug 26, 2019

I edited MAXBUFFERSIZE to increase it to 1000.

Adafruit - A nice way to implement this might be:
#if !defined(MAXBUFFERSIZE)
#define MAXBUFFERSIZE 150
#endif

That would leave things as they are, but allow a user to change the buffer in their own code without editing the header file.

flavio-fernandes added a commit to flavio-fernandes/Adafruit_MQTT_Library that referenced this issue Dec 24, 2019
Fixes adafruit#109
Fixes adafruit#122

After spending a long time pulling my hair to understand why I was
hitting a panic when attempting to read from my registered
subscriptions, I found out that the subscriptions member of the
Adafruit_MQTT instance was corrupted. :(

Turns out the memory corruption was caused by my publish
call, where the payload I was providing was bigger than the
allocated space in the buffer for construction of the packet
(see buffer[MAXBUFFERSIZE]).

To protect myself from ever making this mistake again, I am
proposing a simple logic in publishPacket where instead of
silently corrupting memory, the code uses as much payload
as it can fit in the available space. By seeing the
truncated payload, user can decide whether he/she should
1)break it up into different topics, 2) put the payload on
a diet, or 3) increase MAXBUFFERSIZE.
@flavio-fernandes
Copy link
Contributor

@brentru and @pakokol : Please take a look at #166 and see if that addresses your issue.

flavio-fernandes added a commit to flavio-fernandes/Adafruit_MQTT_Library that referenced this issue Dec 25, 2019
Avoid memory corruption from happening when data payload provided
in Adafruit_MQTT::publishPacket is greater than MAXBUFFERSIZE.

In order to do that, a helper function is being added to calculate
how much space is available for the payload after subtracting what
is used as header.

Pull request adafruit#166
Fixes adafruit#109
Fixes adafruit#122

Signed-off-by: Flavio Fernandes <flavio@flaviof.com>
flavio-fernandes added a commit to flavio-fernandes/Adafruit_MQTT_Library that referenced this issue Dec 25, 2019
Avoid memory corruption from happening when data payload provided
in Adafruit_MQTT::publishPacket is greater than MAXBUFFERSIZE.

In order to do that, a helper function is being added to calculate
how much space is available for the payload after subtracting what
is used as the header.

Pull request adafruit#166
Fixes adafruit#109
Fixes adafruit#122

Signed-off-by: Flavio Fernandes <flavio@flaviof.com>
flavio-fernandes added a commit to flavio-fernandes/Adafruit_MQTT_Library that referenced this issue Dec 25, 2019
Avoid memory corruption from happening when data payload provided
in Adafruit_MQTT::publishPacket is greater than MAXBUFFERSIZE.

In order to do that, a helper function is being added to calculate
how much space is available for the payload after subtracting what
is used as the header.

Pull request adafruit#166
Fixes adafruit#109
Fixes adafruit#122

Signed-off-by: Flavio Fernandes <flavio@flaviof.com>
flavio-fernandes added a commit to flavio-fernandes/Adafruit_MQTT_Library that referenced this issue Dec 25, 2019
Avoid memory corruption from happening when data payload provided
in Adafruit_MQTT::publishPacket is greater than MAXBUFFERSIZE.

In order to do that, a helper function is being added to calculate
how much space is available for the payload after subtracting what
is used as the header.

Pull request adafruit#166
Fixes adafruit#109
Fixes adafruit#122

Signed-off-by: Flavio Fernandes <flavio@flaviof.com>
flavio-fernandes added a commit to flavio-fernandes/Adafruit_MQTT_Library that referenced this issue Aug 29, 2020
Avoid memory corruption from happening when data payload provided
in Adafruit_MQTT::publishPacket is greater than MAXBUFFERSIZE.

In order to do that, a helper function is being added to calculate
how much space is available for the payload after subtracting what
is used as the header.

Pull request adafruit#166
Fixes adafruit#109
Fixes adafruit#122

Signed-off-by: Flavio Fernandes <flavio@flaviof.com>
flavio-fernandes added a commit to flavio-fernandes/Adafruit_MQTT_Library that referenced this issue Aug 29, 2020
Avoid memory corruption from happening when data payload provided
in Adafruit_MQTT::publishPacket is greater than MAXBUFFERSIZE.

In order to do that, a helper function is being added to calculate
how much space is available for the payload after subtracting what
is used as the header.

Pull request adafruit#166
Fixes adafruit#109
Fixes adafruit#122

Signed-off-by: Flavio Fernandes <flavio@flaviof.com>
flavio-fernandes added a commit to flavio-fernandes/Adafruit_MQTT_Library that referenced this issue Aug 29, 2020
Avoid memory corruption from happening when data payload provided
in Adafruit_MQTT::publishPacket is greater than MAXBUFFERSIZE.

In order to do that, a helper function is being added to calculate
how much space is available for the payload after subtracting what
is used as the header.

Pull request adafruit#166
Fixes adafruit#109
Fixes adafruit#122

Signed-off-by: Flavio Fernandes <flavio@flaviof.com>
@jshep321
Copy link

jshep321 commented Oct 6, 2020

I have an issue that might be related? If I publish an outgoing (client to adafruit.io) mqtt message that is >128 characters, it sends ok (as does follow-on outgoing messages). However the next incoming subscriber message causes coredump. My array is 256 characters, fyi. I am seeing coredumps after a certain amount of time with this, which I think is related.

127 character message is fine.

Note the length of the topic seems not relevant in my case.

@flavio-fernandes
Copy link
Contributor

flavio-fernandes commented Oct 6, 2020

I have an issue that might be related? If I publish an outgoing (client to adafruit.io) mqtt message that is >128 characters, it sends ok (as does follow-on outgoing messages). However the next incoming subscriber message causes coredump. My array is 256 characters, fyi. I am seeing coredumps after a certain amount of time with this, which I think is related.

127 character message is fine.

Note the length of the topic seems not relevant in my case.

Yes, that sounds extremely familiar. Try using my fix to see if it helps with the crash. The packet will be
truncated to the max length, but at least you should stop crashing:

#166

Best,

-- flaviof

@jshep321
Copy link

jshep321 commented Oct 7, 2020

Thanks!
I took the dead simple approach in my outgoing mqtt publish function and implemented this to "fix" it:
strncpy (messageToSend, messageIWantToSend, 127);

flavio-fernandes added a commit to flavio-fernandes/Adafruit_MQTT_Library that referenced this issue Apr 2, 2021
Avoid memory corruption from happening when data payload provided
in Adafruit_MQTT::publishPacket is greater than MAXBUFFERSIZE.

In order to do that, a helper function is being added to calculate
how much space is available for the payload after subtracting what
is used as the header.

Pull request adafruit#166
Fixes adafruit#109
Fixes adafruit#122

Signed-off-by: Flavio Fernandes <flavio@flaviof.com>
flavio-fernandes added a commit to flavio-fernandes/Adafruit_MQTT_Library that referenced this issue Apr 2, 2021
Avoid memory corruption from happening when data payload provided
in Adafruit_MQTT::publishPacket is greater than MAXBUFFERSIZE.

In order to do that, a helper function is being added to calculate
how much space is available for the payload after subtracting what
is used as the header.

Pull request adafruit#166
Fixes adafruit#109
Fixes adafruit#122

Signed-off-by: Flavio Fernandes <flavio@flaviof.com>
flavio-fernandes added a commit to flavio-fernandes/Adafruit_MQTT_Library that referenced this issue Apr 2, 2021
Avoid memory corruption from happening when data payload provided
in Adafruit_MQTT::publishPacket is greater than MAXBUFFERSIZE.

In order to do that, a helper function is being added to calculate
how much space is available for the payload after subtracting what
is used as the header.

Pull request adafruit#166
Fixes adafruit#109
Fixes adafruit#122

Signed-off-by: Flavio Fernandes <flavio@flaviof.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
5 participants