Skip to content

Commit 6044657

Browse files
committed
F-2354 - https://fenrir.wolfssl.com/finding/2354 - Add remain_len validation to MqttDecode_UnsubscribeAck
1 parent e5e5d86 commit 6044657

2 files changed

Lines changed: 46 additions & 0 deletions

File tree

src/mqtt_packet.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2194,6 +2194,12 @@ int MqttDecode_UnsubscribeAck(byte *rx_buf, int rx_buf_len,
21942194
if (header_len < 0) {
21952195
return header_len;
21962196
}
2197+
2198+
/* Validate remain_len (need at least packet_id) */
2199+
if (remain_len < MQTT_DATA_LEN_SIZE) {
2200+
return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_MALFORMED_DATA);
2201+
}
2202+
21972203
rx_payload = &rx_buf[header_len];
21982204

21992205
/* Decode variable header */

tests/unit_test.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,45 @@ static void test_decode_publish_resp(void)
513513
"PUBACK remain_len=1: returns MALFORMED_DATA");
514514
}
515515

516+
/* -------------------------------------------------------------------------- */
517+
/* MqttDecode_UnsubscribeAck tests */
518+
/* -------------------------------------------------------------------------- */
519+
static void test_decode_unsuback(void)
520+
{
521+
byte buf[8];
522+
MqttUnsubscribeAck ack;
523+
int rc;
524+
525+
PRINTF("--- MqttDecode_UnsubscribeAck ---");
526+
527+
/* Valid UNSUBACK: remain_len=2 (packet_id) */
528+
buf[0] = MQTT_PACKET_TYPE_SET(MQTT_PACKET_TYPE_UNSUBSCRIBE_ACK); /* 0xB0 */
529+
buf[1] = 2; /* remain_len */
530+
buf[2] = 0; /* packet_id MSB */
531+
buf[3] = 1; /* packet_id LSB */
532+
XMEMSET(&ack, 0, sizeof(ack));
533+
rc = MqttDecode_UnsubscribeAck(buf, 4, &ack);
534+
CHECK(rc > 0, "UNSUBACK remain_len=2: succeeds");
535+
CHECK(ack.packet_id == 1, "UNSUBACK remain_len=2: packet_id == 1");
536+
537+
/* Malformed UNSUBACK: remain_len=0 */
538+
buf[0] = MQTT_PACKET_TYPE_SET(MQTT_PACKET_TYPE_UNSUBSCRIBE_ACK);
539+
buf[1] = 0;
540+
XMEMSET(&ack, 0, sizeof(ack));
541+
rc = MqttDecode_UnsubscribeAck(buf, 2, &ack);
542+
CHECK(rc == MQTT_CODE_ERROR_MALFORMED_DATA,
543+
"UNSUBACK remain_len=0: returns MALFORMED_DATA");
544+
545+
/* Malformed UNSUBACK: remain_len=1 */
546+
buf[0] = MQTT_PACKET_TYPE_SET(MQTT_PACKET_TYPE_UNSUBSCRIBE_ACK);
547+
buf[1] = 1;
548+
buf[2] = 0;
549+
XMEMSET(&ack, 0, sizeof(ack));
550+
rc = MqttDecode_UnsubscribeAck(buf, 3, &ack);
551+
CHECK(rc == MQTT_CODE_ERROR_MALFORMED_DATA,
552+
"UNSUBACK remain_len=1: returns MALFORMED_DATA");
553+
}
554+
516555
int main(int argc, char** argv)
517556
{
518557
(void)argc;
@@ -529,6 +568,7 @@ int main(int argc, char** argv)
529568
test_qos2_ack_arithmetic();
530569
test_decode_suback();
531570
test_decode_publish_resp();
571+
test_decode_unsuback();
532572
#ifdef WOLFMQTT_V5
533573
test_publish_resp_v5_roundtrip();
534574
#endif

0 commit comments

Comments
 (0)