Skip to content

Commit 9ce8d7b

Browse files
XNX02SteveYurongSu
andcommitted
Pipe: Add upper bound check for Pipe request decompression buffer (apache#15699)
Co-authored-by: Steve Yurong Su <[email protected]>
1 parent ee8b8ef commit 9ce8d7b

4 files changed

Lines changed: 45 additions & 0 deletions

File tree

iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonConfig.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,8 @@ public class CommonConfig {
276276
private long pipeReceiverLoginPeriodicVerificationIntervalMs = 300000;
277277
private double pipeReceiverActualToEstimatedMemoryRatio = 3;
278278

279+
private int pipeReceiverReqDecompressedMaxLengthInBytes = 1073741824; // 1GB
280+
279281
private int pipeMaxAllowedHistoricalTsFilePerDataRegion = Integer.MAX_VALUE; // Deprecated
280282
private int pipeMaxAllowedPendingTsFileEpochPerDataRegion = Integer.MAX_VALUE; // Deprecated
281283
private int pipeMaxAllowedPinnedMemTableCount = Integer.MAX_VALUE; // per data region
@@ -1477,6 +1479,22 @@ public double getPipeReceiverActualToEstimatedMemoryRatio() {
14771479
return pipeReceiverActualToEstimatedMemoryRatio;
14781480
}
14791481

1482+
public void setPipeReceiverReqDecompressedMaxLengthInBytes(
1483+
int pipeReceiverReqDecompressedMaxLengthInBytes) {
1484+
if (this.pipeReceiverReqDecompressedMaxLengthInBytes
1485+
== pipeReceiverReqDecompressedMaxLengthInBytes) {
1486+
return;
1487+
}
1488+
this.pipeReceiverReqDecompressedMaxLengthInBytes = pipeReceiverReqDecompressedMaxLengthInBytes;
1489+
logger.info(
1490+
"pipeReceiverReqDecompressedMaxLengthInBytes is set to {}.",
1491+
pipeReceiverReqDecompressedMaxLengthInBytes);
1492+
}
1493+
1494+
public int getPipeReceiverReqDecompressedMaxLengthInBytes() {
1495+
return pipeReceiverReqDecompressedMaxLengthInBytes;
1496+
}
1497+
14801498
public int getPipeMaxAllowedHistoricalTsFilePerDataRegion() {
14811499
return pipeMaxAllowedHistoricalTsFilePerDataRegion;
14821500
}

iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/config/PipeConfig.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,10 @@ public double getPipeReceiverActualToEstimatedMemoryRatio() {
329329
return COMMON_CONFIG.getPipeReceiverActualToEstimatedMemoryRatio();
330330
}
331331

332+
public int getPipeReceiverReqDecompressedMaxLengthInBytes() {
333+
return COMMON_CONFIG.getPipeReceiverReqDecompressedMaxLengthInBytes();
334+
}
335+
332336
/////////////////////////////// Hybrid Mode ///////////////////////////////
333337

334338
public int getPipeMaxAllowedHistoricalTsFilePerDataRegion() {
@@ -614,6 +618,9 @@ public void printAllConfigs() {
614618
LOGGER.info(
615619
"PipeReceiverActualToEstimatedMemoryRatio: {}",
616620
getPipeReceiverActualToEstimatedMemoryRatio());
621+
LOGGER.info(
622+
"PipeReceiverReqDecompressedMaxLengthInBytes: {}",
623+
getPipeReceiverReqDecompressedMaxLengthInBytes());
617624

618625
LOGGER.info(
619626
"PipeMaxAllowedHistoricalTsFilePerDataRegion: {}",

iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/config/PipeDescriptor.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,11 @@ public static void loadPipeInternalConfig(CommonConfig config, TrimProperties pr
435435
properties.getProperty(
436436
"pipe_receiver_actual_to_estimated_memory_ratio",
437437
Double.toString(config.getPipeReceiverActualToEstimatedMemoryRatio()))));
438+
config.setPipeReceiverReqDecompressedMaxLengthInBytes(
439+
Integer.parseInt(
440+
properties.getProperty(
441+
"pipe_receiver_req_decompressed_max_length_in_bytes",
442+
String.valueOf(config.getPipeReceiverReqDecompressedMaxLengthInBytes()))));
438443

439444
config.setPipeMaxAllowedHistoricalTsFilePerDataRegion(
440445
Integer.parseInt(

iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/connector/payload/thrift/request/PipeTransferCompressedReq.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
package org.apache.iotdb.commons.pipe.connector.payload.thrift.request;
2121

22+
import org.apache.iotdb.commons.pipe.config.PipeConfig;
2223
import org.apache.iotdb.commons.pipe.connector.compressor.PipeCompressor;
2324
import org.apache.iotdb.commons.pipe.connector.compressor.PipeCompressorFactory;
2425
import org.apache.iotdb.service.rpc.thrift.TPipeTransferReq;
@@ -91,6 +92,7 @@ public static TPipeTransferReq fromTPipeTransferReq(final TPipeTransferReq trans
9192
compressors.add(
9293
PipeCompressorFactory.getCompressor(ReadWriteIOUtils.readByte(compressedBuffer)));
9394
uncompressedLengths.add(ReadWriteIOUtils.readInt(compressedBuffer));
95+
checkDecompressedLength(uncompressedLengths.get(i));
9496
}
9597

9698
byte[] body = new byte[compressedBuffer.remaining()];
@@ -110,6 +112,19 @@ public static TPipeTransferReq fromTPipeTransferReq(final TPipeTransferReq trans
110112
return decompressedReq;
111113
}
112114

115+
/** This method is used to prevent decompression bomb attacks. */
116+
private static void checkDecompressedLength(final int decompressedLength)
117+
throws IllegalArgumentException {
118+
final int maxDecompressedLength =
119+
PipeConfig.getInstance().getPipeReceiverReqDecompressedMaxLengthInBytes();
120+
if (decompressedLength < 0 || decompressedLength > maxDecompressedLength) {
121+
throw new IllegalArgumentException(
122+
String.format(
123+
"Decompressed length should be between 0 and %d, but got %d.",
124+
maxDecompressedLength, decompressedLength));
125+
}
126+
}
127+
113128
/**
114129
* For air-gap connectors. Generate the bytes of a compressed req from the bytes of original req.
115130
*/

0 commit comments

Comments
 (0)