From 182623db2a1080a75807fed56ac54f6a175f9f92 Mon Sep 17 00:00:00 2001 From: dxbjavid Date: Fri, 22 May 2026 09:09:51 +0530 Subject: [PATCH] SN_Decode_GWInfo: reject extended-length frame too short for gwId An MQTT-SN GWINFO frame with the 0x01 SN_PACKET_LEN_IND prefix consumes three header bytes (indicator + two-byte length) before the message-type and gateway-ID bytes that SN_Decode_GWInfo reads via *rx_payload++. The existing minimum-size guard (total_len < 3) was sized for the short-form header (one byte) and accepts an extended-length frame whose decoded total_len equals the bytes the function has already consumed for the header (3) or sits one byte short of also covering the gateway-ID byte (4). In both cases the type / gwId reads run past the caller-supplied rx_buf bound; a page-guarded reproducer (mmap + adjacent PROT_NONE page) shows SIGBUS on the *rx_payload++ at offset 4. Replace the fixed "< 3" minimum with a check against (rx_payload - rx_buf) + 2, which is the number of bytes the function must still read after the length-indicator block (one message-type byte plus one gateway-ID byte). This covers both header layouts uniformly: the short form keeps the prior >= 3 minimum, and the extended-length form requires >= 5. After the patch the page-guarded frame returns MQTT_CODE_ERROR_MALFORMED_DATA cleanly and the existing valid short-form and extended-length-with-address inputs continue to decode. --- src/mqtt_sn_packet.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/mqtt_sn_packet.c b/src/mqtt_sn_packet.c index 80e5a88e..3157f653 100644 --- a/src/mqtt_sn_packet.c +++ b/src/mqtt_sn_packet.c @@ -291,7 +291,15 @@ int SN_Decode_GWInfo(byte *rx_buf, int rx_buf_len, SN_GwInfo *gw_info) if (total_len > rx_buf_len) { return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_OUT_OF_BUFFER); } - if (total_len < 3) { + /* Reject a frame whose total_len cannot cover the bytes still to be read + * after the length-indicator block (message type + gateway ID). The + * short-form header consumes one byte and the extended-length form + * consumes three, so the prior fixed "< 3" minimum was only valid for + * the short form: an extended-length GWINFO with total_len <= the + * header bytes already consumed would slip past it and the + * *rx_payload++ reads below would walk past the caller-supplied + * buffer. */ + if (total_len < (word16)(rx_payload - rx_buf) + 2) { return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_MALFORMED_DATA); } /* Check message type */