This is an automated email from the ASF dual-hosted git repository.

yiguolei pushed a commit to branch branch-4.1
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-4.1 by this push:
     new 8d62a18f12a branch-4.1: [fix](fe) Bound length in 
MysqlProto.readLenEncodedString #63604 (#64059)
8d62a18f12a is described below

commit 8d62a18f12a059f4313b90ea99148896378f6f29
Author: github-actions[bot] 
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Thu Jun 4 09:32:15 2026 +0800

    branch-4.1: [fix](fe) Bound length in MysqlProto.readLenEncodedString 
#63604 (#64059)
    
    Cherry-picked from #63604
    
    Co-authored-by: MarkLee131 <[email protected]>
---
 .../java/org/apache/doris/mysql/MysqlProto.java    |  8 +++
 .../doris/mysql/MysqlProtoLenEncStringTest.java    | 61 ++++++++++++++++++++++
 2 files changed, 69 insertions(+)

diff --git a/fe/fe-core/src/main/java/org/apache/doris/mysql/MysqlProto.java 
b/fe/fe-core/src/main/java/org/apache/doris/mysql/MysqlProto.java
index 4f8914ef9fc..4e495a428ed 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/mysql/MysqlProto.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/mysql/MysqlProto.java
@@ -329,6 +329,14 @@ public class MysqlProto {
 
     public static byte[] readLenEncodedString(ByteBuffer buffer) {
         long length = readVInt(buffer);
+        // The string payload must fit in the bytes actually remaining in the 
packet.
+        // Without this bound an attacker-controlled length is passed straight 
to
+        // new byte[(int) length], where the (int) cast can go negative or 
request
+        // up to ~2 GiB from a few bytes on the wire.
+        if (length < 0 || length > buffer.remaining()) {
+            throw new IllegalArgumentException("invalid length-encoded string 
length: " + length
+                    + ", remaining: " + buffer.remaining());
+        }
         byte[] buf = new byte[(int) length];
         buffer.get(buf);
         return buf;
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/mysql/MysqlProtoLenEncStringTest.java
 
b/fe/fe-core/src/test/java/org/apache/doris/mysql/MysqlProtoLenEncStringTest.java
new file mode 100644
index 00000000000..237632eb00b
--- /dev/null
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/mysql/MysqlProtoLenEncStringTest.java
@@ -0,0 +1,61 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.mysql;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
+
+public class MysqlProtoLenEncStringTest {
+
+    // A length-encoded string whose declared length exceeds the bytes actually
+    // present must be rejected, not passed to new byte[(int) length]. Before 
the
+    // bound, a 0xFE lead byte plus an 8-byte length let a handful of bytes 
request
+    // ~2 GiB, and a high-bit length cast to a negative size.
+    @Test
+    public void readLenEncodedStringRejectsOversizedLength() {
+        ByteBuffer buffer = ByteBuffer.allocate(9);
+        buffer.put((byte) 0xFE); // 8-byte length follows
+        buffer.put(new byte[] {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 
0x7F, 0, 0, 0, 0}); // 0x7FFFFFFF
+        buffer.flip();
+        Assert.assertThrows(IllegalArgumentException.class,
+                () -> MysqlProto.readLenEncodedString(buffer));
+    }
+
+    @Test
+    public void readLenEncodedStringRejectsNegativeCastLength() {
+        ByteBuffer buffer = ByteBuffer.allocate(9);
+        buffer.put((byte) 0xFE);
+        buffer.put(new byte[] {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 
0xFF, 0, 0, 0, 0}); // (int) -> -1
+        buffer.flip();
+        Assert.assertThrows(IllegalArgumentException.class,
+                () -> MysqlProto.readLenEncodedString(buffer));
+    }
+
+    @Test
+    public void readLenEncodedStringAcceptsValidPayload() {
+        byte[] payload = "abc".getBytes(StandardCharsets.UTF_8);
+        ByteBuffer buffer = ByteBuffer.allocate(1 + payload.length);
+        buffer.put((byte) payload.length); // single-byte length < 251
+        buffer.put(payload);
+        buffer.flip();
+        Assert.assertArrayEquals(payload, 
MysqlProto.readLenEncodedString(buffer));
+    }
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to