This is an automated email from the ASF dual-hosted git repository.
cshannon pushed a commit to branch activemq-6.1.x
in repository https://gitbox.apache.org/repos/asf/activemq.git
The following commit(s) were added to refs/heads/activemq-6.1.x by this push:
new f6b062fff0 AMQ-9810 - Add additional validation for MQTT control
packets
f6b062fff0 is described below
commit f6b062fff00df031a2766873a250a9f7f9ca9697
Author: Christopher L. Shannon <[email protected]>
AuthorDate: Fri Nov 21 14:33:27 2025 -0500
AMQ-9810 - Add additional validation for MQTT control packets
Validate that the remaining length field is the correct number of bytes
(cherry picked from commit 165e80bad459054bb8e422d58c2d1b42ab90003b)
---
.../apache/activemq/transport/mqtt/MQTTCodec.java | 6 ++++
.../activemq/transport/mqtt/MQTTCodecTest.java | 33 ++++++++++++++++++++++
2 files changed, 39 insertions(+)
diff --git
a/activemq-mqtt/src/main/java/org/apache/activemq/transport/mqtt/MQTTCodec.java
b/activemq-mqtt/src/main/java/org/apache/activemq/transport/mqtt/MQTTCodec.java
index 12c9981db2..06efe49910 100644
---
a/activemq-mqtt/src/main/java/org/apache/activemq/transport/mqtt/MQTTCodec.java
+++
b/activemq-mqtt/src/main/java/org/apache/activemq/transport/mqtt/MQTTCodec.java
@@ -25,6 +25,8 @@ import org.fusesource.mqtt.codec.MQTTFrame;
public class MQTTCodec {
+ private static final int MAX_MULTIPLIER = (int) Math.pow(2, 21);
+
private final MQTTFrameSink frameSink;
private final MQTTWireFormat wireFormat;
@@ -159,6 +161,10 @@ public class MQTTCodec {
int i = 0;
while (i++ < readSize) {
digit = data.readByte();
+ // MQTT protocol limits Remaining Length to 4 bytes
+ if (multiplier == MAX_MULTIPLIER && (digit & 128) != 0) {
+ throw new IOException("Remaining length exceeds 4 bytes");
+ }
length += (digit & 0x7F) * multiplier;
multiplier <<= 7;
if ((digit & 0x80) == 0) {
diff --git
a/activemq-mqtt/src/test/java/org/apache/activemq/transport/mqtt/MQTTCodecTest.java
b/activemq-mqtt/src/test/java/org/apache/activemq/transport/mqtt/MQTTCodecTest.java
index 49722d8eec..b14fba8c58 100644
---
a/activemq-mqtt/src/test/java/org/apache/activemq/transport/mqtt/MQTTCodecTest.java
+++
b/activemq-mqtt/src/test/java/org/apache/activemq/transport/mqtt/MQTTCodecTest.java
@@ -21,6 +21,7 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import java.io.IOException;
import java.net.ProtocolException;
import java.util.ArrayList;
import java.util.List;
@@ -314,4 +315,36 @@ public class MQTTCodecTest {
LOG.info("Total time to process: {}",
TimeUnit.MILLISECONDS.toSeconds(duration));
}
+
+
+ @Test
+ public void testParseInvalidRemainingLengthField() throws Exception {
+ try {
+ // The maximum bytes in the remaining length field is 4
+ // The most significant bit is used to indicate that there are
following bytes in the representation.
+ // If the most significant digit is a 1 in byte 4 that is an error
and invalid length field
+ final Buffer buffer = new Buffer(new byte[]{CONNECT.TYPE, (byte)
0x81, (byte) 0x81,
+ (byte) 0x81, (byte) 0x81});
+ final DataByteArrayInputStream input = new
DataByteArrayInputStream(buffer);
+ codec.parse(input, buffer.length());
+ fail("Parsing should have failed invalid remaining length field");
+ } catch (IOException e) {
+ // expected
+ }
+ }
+
+ @Test
+ public void testPartialReadInvalidRemainingLengthField() throws Exception {
+ // Test Invalid remaining field checking still works with partial reads
+ Buffer buffer = new Buffer(new byte[]{CONNECT.TYPE, (byte) 0x81,
(byte) 0x81});
+ codec.parse(new DataByteArrayInputStream(buffer), buffer.length());
+ try {
+ buffer = new Buffer(new byte[]{(byte) 0x81, (byte) 0x81});
+ codec.parse(new DataByteArrayInputStream(buffer), buffer.length());
+ fail("Parsing should have failed invalid remaining length field");
+ } catch (IOException e) {
+ // expected
+ }
+ }
+
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
For further information, visit: https://activemq.apache.org/contact