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 9340ccfe44 AMQ-9810 - Add additional validation for MQTT wireformat
9340ccfe44 is described below

commit 9340ccfe44e18ad6bf2278d71ef955ff866a5942
Author: Christopher L. Shannon <[email protected]>
AuthorDate: Fri Nov 21 17:53:36 2025 -0500

    AMQ-9810 - Add additional validation for MQTT wireformat
    
    Validate that the remaining length field is the correct number of bytes
    in MQTTWireFormat
    
    (cherry picked from commit d0df9e24313dfa4a0a7df8494a95e4cf0e94c64b)
---
 .../org/apache/activemq/transport/mqtt/MQTTCodec.java   |  2 +-
 .../apache/activemq/transport/mqtt/MQTTWireFormat.java  |  6 ++++++
 .../apache/activemq/transport/mqtt/MQTTCodecTest.java   | 17 ++++++++++++++++-
 3 files changed, 23 insertions(+), 2 deletions(-)

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 06efe49910..66a0ae5eb0 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,7 +25,7 @@ import org.fusesource.mqtt.codec.MQTTFrame;
 
 public class MQTTCodec {
 
-    private static final int MAX_MULTIPLIER = (int) Math.pow(2, 21);
+    static final int MAX_MULTIPLIER = (int) Math.pow(2, 21);
 
     private final MQTTFrameSink frameSink;
     private final MQTTWireFormat wireFormat;
diff --git 
a/activemq-mqtt/src/main/java/org/apache/activemq/transport/mqtt/MQTTWireFormat.java
 
b/activemq-mqtt/src/main/java/org/apache/activemq/transport/mqtt/MQTTWireFormat.java
index 382247f018..9e79fd25f4 100644
--- 
a/activemq-mqtt/src/main/java/org/apache/activemq/transport/mqtt/MQTTWireFormat.java
+++ 
b/activemq-mqtt/src/main/java/org/apache/activemq/transport/mqtt/MQTTWireFormat.java
@@ -29,6 +29,8 @@ import org.apache.activemq.wireformat.WireFormat;
 import org.fusesource.hawtbuf.Buffer;
 import org.fusesource.mqtt.codec.MQTTFrame;
 
+import static org.apache.activemq.transport.mqtt.MQTTCodec.MAX_MULTIPLIER;
+
 /**
  * Implements marshalling and unmarsalling the <a
  * href="http://mqtt.org/";>MQTT</a> protocol.
@@ -92,6 +94,10 @@ public class MQTTWireFormat implements WireFormat {
             digit = dataIn.readByte();
             length += (digit & 0x7F) * multiplier;
             multiplier <<= 7;
+            // MQTT protocol limits Remaining Length to 4 bytes
+            if (multiplier == MAX_MULTIPLIER && (digit & 128) != 0) {
+                throw new IOException("Remaining length exceeds 4 bytes");
+            }
         }
         while ((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 b14fba8c58..994bff4e67 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
@@ -27,6 +27,7 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.TimeUnit;
 
+import org.apache.activemq.util.ByteSequence;
 import org.fusesource.hawtbuf.Buffer;
 import org.fusesource.hawtbuf.DataByteArrayInputStream;
 import org.fusesource.hawtbuf.DataByteArrayOutputStream;
@@ -316,7 +317,6 @@ public class MQTTCodecTest {
         LOG.info("Total time to process: {}", 
TimeUnit.MILLISECONDS.toSeconds(duration));
     }
 
-
     @Test
     public void testParseInvalidRemainingLengthField() throws Exception {
         try {
@@ -330,6 +330,7 @@ public class MQTTCodecTest {
             fail("Parsing should have failed invalid remaining length field");
         } catch (IOException e) {
             // expected
+            assertEquals("Remaining length exceeds 4 bytes", e.getMessage());
         }
     }
 
@@ -344,6 +345,20 @@ public class MQTTCodecTest {
             fail("Parsing should have failed invalid remaining length field");
         } catch (IOException e) {
             // expected
+            assertEquals("Remaining length exceeds 4 bytes", e.getMessage());
+        }
+    }
+
+    @Test
+    public void testUnmarshalInvalidRemainingLengthField() {
+        try {
+            // Test Invalid remaining field checking using the marshaller
+            wireFormat.unmarshal(new ByteSequence(new byte[]{CONNECT.TYPE, 
(byte) 0x81, (byte) 0x81,
+                    (byte) 0x81, (byte) 0x81}));
+            fail("Parsing should have failed invalid remaining length field");
+        } catch (IOException e) {
+            // expected
+            assertEquals("Remaining length exceeds 4 bytes", e.getMessage());
         }
     }
 


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
For further information, visit: https://activemq.apache.org/contact


Reply via email to