1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
|
From: Markus Koschany <apo@debian.org>
Date: Sun, 1 Jan 2023 17:07:49 +0100
Subject: CVE-2021-37136
Bug-Debian: https://bugs.debian.org/1014769
Origin: https://github.com/netty/netty/commit/41d3d61a61608f2223bb364955ab2045dd5e4020
---
.../handler/codec/compression/Bzip2BlockDecompressor.java | 5 +++++
.../netty/handler/codec/compression/Bzip2Constants.java | 2 ++
.../io/netty/handler/codec/compression/Bzip2Decoder.java | 15 ++++++++-------
3 files changed, 15 insertions(+), 7 deletions(-)
diff --git a/codec/src/main/java/io/netty/handler/codec/compression/Bzip2BlockDecompressor.java b/codec/src/main/java/io/netty/handler/codec/compression/Bzip2BlockDecompressor.java
index ae05568..5a0b497 100644
--- a/codec/src/main/java/io/netty/handler/codec/compression/Bzip2BlockDecompressor.java
+++ b/codec/src/main/java/io/netty/handler/codec/compression/Bzip2BlockDecompressor.java
@@ -228,6 +228,11 @@ final class Bzip2BlockDecompressor {
bwtBlock[bwtBlockLength++] = nextByte;
}
}
+ if (bwtBlockLength > MAX_BLOCK_LENGTH) {
+ throw new DecompressionException("block length exceeds max block length: "
+ + bwtBlockLength + " > " + MAX_BLOCK_LENGTH);
+ }
+
this.bwtBlockLength = bwtBlockLength;
initialiseInverseBWT();
return true;
diff --git a/codec/src/main/java/io/netty/handler/codec/compression/Bzip2Constants.java b/codec/src/main/java/io/netty/handler/codec/compression/Bzip2Constants.java
index c0283a7..21b9a2b 100644
--- a/codec/src/main/java/io/netty/handler/codec/compression/Bzip2Constants.java
+++ b/codec/src/main/java/io/netty/handler/codec/compression/Bzip2Constants.java
@@ -49,6 +49,8 @@ final class Bzip2Constants {
static final int MIN_BLOCK_SIZE = 1;
static final int MAX_BLOCK_SIZE = 9;
+ static final int MAX_BLOCK_LENGTH = MAX_BLOCK_SIZE * BASE_BLOCK_SIZE;
+
/**
* Maximum possible Huffman alphabet size.
*/
diff --git a/codec/src/main/java/io/netty/handler/codec/compression/Bzip2Decoder.java b/codec/src/main/java/io/netty/handler/codec/compression/Bzip2Decoder.java
index b66ff59..3fc1001 100644
--- a/codec/src/main/java/io/netty/handler/codec/compression/Bzip2Decoder.java
+++ b/codec/src/main/java/io/netty/handler/codec/compression/Bzip2Decoder.java
@@ -291,26 +291,27 @@ public class Bzip2Decoder extends ByteToMessageDecoder {
}
final int blockLength = blockDecompressor.blockLength();
- final ByteBuf uncompressed = ctx.alloc().buffer(blockLength);
- boolean success = false;
+ ByteBuf uncompressed = ctx.alloc().buffer(blockLength);
try {
int uncByte;
while ((uncByte = blockDecompressor.read()) >= 0) {
uncompressed.writeByte(uncByte);
}
-
+ // We did read all the data, lets reset the state and do the CRC check.
+ currentState = State.INIT_BLOCK;
int currentBlockCRC = blockDecompressor.checkCRC();
streamCRC = (streamCRC << 1 | streamCRC >>> 31) ^ currentBlockCRC;
out.add(uncompressed);
- success = true;
+ uncompressed = null;
} finally {
- if (!success) {
+ if (uncompressed != null) {
uncompressed.release();
}
}
- currentState = State.INIT_BLOCK;
- break;
+ // Return here so the ByteBuf that was put in the List will be forwarded to the user and so can be
+ // released as soon as possible.
+ return;
case EOF:
in.skipBytes(in.readableBytes());
return;
|