From ffd44fb42438f62c740e941fe566b40838fc295b Mon Sep 17 00:00:00 2001 From: Eun0us Date: Tue, 10 Feb 2026 18:42:35 +0100 Subject: [PATCH] fix: fix signed integer overflow in remaining length decoding The expression (buffer[i] & 0x7f) << (7 * (i - 1)) performs a left shift on a signed int. When i >= 5, the shift amount reaches 28+ and 0x7f << 28 overflows INT_MAX, which is undefined behavior. Per MQTT 3.1.1 section 2.2.3, the Remaining Length field uses at most 4 continuation bytes, so limit the decoding loop accordingly. Also cast to size_t in mqtt_get_total_length() where totlen is already size_t. Affects mqtt_get_total_length() and mqtt_get_publish_data(). Found via coverage-guided fuzzing (libFuzzer + UBSan). --- lib/mqtt_msg.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/mqtt_msg.c b/lib/mqtt_msg.c index ccfcdc2..9bd01d4 100644 --- a/lib/mqtt_msg.c +++ b/lib/mqtt_msg.c @@ -121,8 +121,8 @@ size_t mqtt_get_total_length(const uint8_t *buffer, size_t length, int *fixed_si int i; size_t totlen = 0; - for (i = 1; i < length; ++i) { - totlen += (buffer[i] & 0x7f) << (7 * (i - 1)); + for (i = 1; i < length && i <= 4; ++i) { + totlen += (size_t)(buffer[i] & 0x7f) << (7 * (i - 1)); if ((buffer[i] & 0x80) == 0) { ++i; @@ -208,7 +208,7 @@ char *mqtt_get_publish_data(uint8_t *buffer, size_t *length) int blength = *length; *length = 0; - for (i = 1; i < blength; ++i) { + for (i = 1; i < blength && i <= 4; ++i) { totlen += (buffer[i] & 0x7f) << (7 * (i - 1)); if ((buffer[i] & 0x80) == 0) {