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

justinchen pushed a commit to branch dev/1.3
in repository https://gitbox.apache.org/repos/asf/iotdb.git


The following commit(s) were added to refs/heads/dev/1.3 by this push:
     new b53b1a62838 [To dev/1.3] Pipe: Add upper bound check for Pipe request 
decompression buffer (#15699) (#15806)
b53b1a62838 is described below

commit b53b1a6283845e3f90fa2e96df2a047536453a43
Author: nanxiang xia <[email protected]>
AuthorDate: Thu Jul 3 14:54:42 2025 +0800

    [To dev/1.3] Pipe: Add upper bound check for Pipe request decompression 
buffer (#15699) (#15806)
    
    Co-authored-by: Steve Yurong Su <[email protected]>
---
 .../org/apache/iotdb/commons/conf/CommonConfig.java    | 18 ++++++++++++++++++
 .../apache/iotdb/commons/pipe/config/PipeConfig.java   |  7 +++++++
 .../iotdb/commons/pipe/config/PipeDescriptor.java      |  5 +++++
 .../thrift/request/PipeTransferCompressedReq.java      | 15 +++++++++++++++
 4 files changed, 45 insertions(+)

diff --git 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonConfig.java
 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonConfig.java
index 038581bf1f5..04d2263ca31 100644
--- 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonConfig.java
+++ 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonConfig.java
@@ -276,6 +276,8 @@ public class CommonConfig {
   private long pipeReceiverLoginPeriodicVerificationIntervalMs = 300000;
   private double pipeReceiverActualToEstimatedMemoryRatio = 3;
 
+  private int pipeReceiverReqDecompressedMaxLengthInBytes = 1073741824; // 1GB
+
   private int pipeMaxAllowedHistoricalTsFilePerDataRegion = Integer.MAX_VALUE; 
// Deprecated
   private int pipeMaxAllowedPendingTsFileEpochPerDataRegion = 
Integer.MAX_VALUE; // Deprecated
   private int pipeMaxAllowedPinnedMemTableCount = Integer.MAX_VALUE; // per 
data region
@@ -1479,6 +1481,22 @@ public class CommonConfig {
     return pipeReceiverActualToEstimatedMemoryRatio;
   }
 
+  public void setPipeReceiverReqDecompressedMaxLengthInBytes(
+      int pipeReceiverReqDecompressedMaxLengthInBytes) {
+    if (this.pipeReceiverReqDecompressedMaxLengthInBytes
+        == pipeReceiverReqDecompressedMaxLengthInBytes) {
+      return;
+    }
+    this.pipeReceiverReqDecompressedMaxLengthInBytes = 
pipeReceiverReqDecompressedMaxLengthInBytes;
+    logger.info(
+        "pipeReceiverReqDecompressedMaxLengthInBytes is set to {}.",
+        pipeReceiverReqDecompressedMaxLengthInBytes);
+  }
+
+  public int getPipeReceiverReqDecompressedMaxLengthInBytes() {
+    return pipeReceiverReqDecompressedMaxLengthInBytes;
+  }
+
   public int getPipeMaxAllowedHistoricalTsFilePerDataRegion() {
     return pipeMaxAllowedHistoricalTsFilePerDataRegion;
   }
diff --git 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/config/PipeConfig.java
 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/config/PipeConfig.java
index be0c70d7f42..957717cb27f 100644
--- 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/config/PipeConfig.java
+++ 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/config/PipeConfig.java
@@ -329,6 +329,10 @@ public class PipeConfig {
     return COMMON_CONFIG.getPipeReceiverActualToEstimatedMemoryRatio();
   }
 
+  public int getPipeReceiverReqDecompressedMaxLengthInBytes() {
+    return COMMON_CONFIG.getPipeReceiverReqDecompressedMaxLengthInBytes();
+  }
+
   /////////////////////////////// Hybrid Mode ///////////////////////////////
 
   public int getPipeMaxAllowedHistoricalTsFilePerDataRegion() {
@@ -614,6 +618,9 @@ public class PipeConfig {
     LOGGER.info(
         "PipeReceiverActualToEstimatedMemoryRatio: {}",
         getPipeReceiverActualToEstimatedMemoryRatio());
+    LOGGER.info(
+        "PipeReceiverReqDecompressedMaxLengthInBytes: {}",
+        getPipeReceiverReqDecompressedMaxLengthInBytes());
 
     LOGGER.info(
         "PipeMaxAllowedHistoricalTsFilePerDataRegion: {}",
diff --git 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/config/PipeDescriptor.java
 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/config/PipeDescriptor.java
index 7086ff731bf..2feecc0ee56 100644
--- 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/config/PipeDescriptor.java
+++ 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/config/PipeDescriptor.java
@@ -435,6 +435,11 @@ public class PipeDescriptor {
             properties.getProperty(
                 "pipe_receiver_actual_to_estimated_memory_ratio",
                 
Double.toString(config.getPipeReceiverActualToEstimatedMemoryRatio()))));
+    config.setPipeReceiverReqDecompressedMaxLengthInBytes(
+        Integer.parseInt(
+            properties.getProperty(
+                "pipe_receiver_req_decompressed_max_length_in_bytes",
+                
String.valueOf(config.getPipeReceiverReqDecompressedMaxLengthInBytes()))));
 
     config.setPipeMaxAllowedHistoricalTsFilePerDataRegion(
         Integer.parseInt(
diff --git 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/connector/payload/thrift/request/PipeTransferCompressedReq.java
 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/connector/payload/thrift/request/PipeTransferCompressedReq.java
index b92b2d4256a..e4c4278467b 100644
--- 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/connector/payload/thrift/request/PipeTransferCompressedReq.java
+++ 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/connector/payload/thrift/request/PipeTransferCompressedReq.java
@@ -19,6 +19,7 @@
 
 package org.apache.iotdb.commons.pipe.connector.payload.thrift.request;
 
+import org.apache.iotdb.commons.pipe.config.PipeConfig;
 import org.apache.iotdb.commons.pipe.connector.compressor.PipeCompressor;
 import 
org.apache.iotdb.commons.pipe.connector.compressor.PipeCompressorFactory;
 import org.apache.iotdb.service.rpc.thrift.TPipeTransferReq;
@@ -91,6 +92,7 @@ public class PipeTransferCompressedReq extends 
TPipeTransferReq {
       compressors.add(
           
PipeCompressorFactory.getCompressor(ReadWriteIOUtils.readByte(compressedBuffer)));
       uncompressedLengths.add(ReadWriteIOUtils.readInt(compressedBuffer));
+      checkDecompressedLength(uncompressedLengths.get(i));
     }
 
     byte[] body = new byte[compressedBuffer.remaining()];
@@ -110,6 +112,19 @@ public class PipeTransferCompressedReq extends 
TPipeTransferReq {
     return decompressedReq;
   }
 
+  /** This method is used to prevent decompression bomb attacks. */
+  private static void checkDecompressedLength(final int decompressedLength)
+      throws IllegalArgumentException {
+    final int maxDecompressedLength =
+        
PipeConfig.getInstance().getPipeReceiverReqDecompressedMaxLengthInBytes();
+    if (decompressedLength < 0 || decompressedLength > maxDecompressedLength) {
+      throw new IllegalArgumentException(
+          String.format(
+              "Decompressed length should be between 0 and %d, but got %d.",
+              maxDecompressedLength, decompressedLength));
+    }
+  }
+
   /**
    * For air-gap connectors. Generate the bytes of a compressed req from the 
bytes of original req.
    */

Reply via email to