OASIS Mailing List ArchivesView the OASIS mailing list archive below
or browse/search using MarkMail.

 


Help: OASIS Mailing Lists Help | MarkMail Help

mqtt message

[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]


Subject: Erratum: Error in Remaining Length Decoding Algorithm MQTT 3.1.1 § 2.2.3


 

While testing MQTT, I discovered an error in the Standard that will cause implementations to fail upon reception of PUBLISH messages in which the combination of topic length, QoS level, and payload size result in a fixed header remaining length > 2,097,151. What is the process to amend the specification to help developers of MQTT implementations to avoid this failure? (I reviewed the Approved Errata process, but am seeking more guidance for how the MQTT TC is managing errata.)

 

The culprit is an incorrect loop termination check in the algorithm for decoding the remaining length field provided in § 2.2.3.  It causes decoding to fail for all encoded values greater than 2,097,151. Consequently, reception fails with valid PUBLISH messages for which 2,097,152 ≤ remaining length ≤ 268,435,455 holds. This failure is not recoverable by retransmission.

 

The algorithm can be corrected by moving the location of the loop termination check within the loop body as shown in the pseudo code below. Although the algorithm is contained in a section labeled "non-normative comment", a correction to the Standard seems desirable because developers are likely to copy the algorithm verbatim.

 

Applicability and Impact

 

This error affects implementations using the algorithm in the MQTT 3.1.1 Standard. Implementations using other algorithms, including the older algorithm contained in MQTT 3.1, will not encounter this problem.  However, as noted in MQTT-29 item 3, the MQTT 3.1 algorithm is susceptible to buffer overflow attacks and similar problems because it cannot detect malformed remaining length encoding.

 

Session partners of affected implementations can be indirectly affected because they will not receive acknowledgements from affected systems when using durable sessions and QoS > 0 because the failure is unrecoverable by retransmission.

 

Origin

 

This error does not appear in the MQTT 3.1 Standard, and seems to have been introduced in MQTT 3.1.1 WD08 or WD09, possibly in response to safety concerns raised in MQTT-29 (item 3).

 

 

Description of Error

 

Non-normative comments in § 2.2.3 presents the following algorithm for decoding the remaining length field. (line numbers and emphasis added) :

 

1    multiplier = 1

2    value = 0

3

4    do

5        encodedByte = 'next byte from stream'

6        value += (encodedByte AND 127) * multiplier

7        multiplier *= 128

8        if (multiplier > 128*128*128)  << ? Fails

9            throw Error(Malformed Remaining Length)

10   while ((encodedByte AND 128) != 0)

 

 

The range check (line 8) fails because 4 bytes are required to encode values greater than 2,097,151.  In the fourth iteration of the do-while loop, the multiplier exceeds the limit of 128*128*128 causing the range check to fail.

 

Suggested Correction to the MQTT 3.1.1 Standard

 

To correct this error, it is only necessary to move the range check so that it precedes the multiplier update.  The corrected algorithm appears below:

 

 

1    multiplier = 1

2    value = 0

3

4    do

5        encodedByte = 'next byte from stream'

6        value += (encodedByte AND 127) * multiplier

7        if (multiplier > 128*128*128)                

8            throw Error(Malformed Remaining Length)

9        multiplier *= 128  <<- Now follows range check

10   while ((encodedByte AND 128) != 0)

 

 

With this change, the algorithm correctly encodes all values from 0 to 268,435,455, and rejects encoded values greater than 268,435,455 as required by the Standard.   [NB: Both the original and corrected version contain an unnecessary multiplication (line 8 and 9) respectively on the last iteration of the loop.]

 

Thank you,

 

Ed Briggs

Microsoft Corporation

 

 

 

 



[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]