Remove lz4-java dependency and fix CVE-2021-43797
This commit is contained in:
parent
6ad7025dd7
commit
f756b66d85
231
CVE-2021-43797-pre.patch
Normal file
231
CVE-2021-43797-pre.patch
Normal file
@ -0,0 +1,231 @@
|
||||
From 74187ebf123de466cb31270213b2464267a1cfd4 Mon Sep 17 00:00:00 2001
|
||||
From: Norman Maurer <norman_maurer@apple.com>
|
||||
Date: Wed, 26 Feb 2020 09:49:39 +0100
|
||||
Subject: [PATCH 1/1] More strict parsing of initial line / http headers
|
||||
(#10058)
|
||||
|
||||
Motivation:
|
||||
|
||||
Our parsing of the initial line / http headers did treat some characters as separators which should better trigger an exception during parsing.
|
||||
|
||||
Modifications:
|
||||
|
||||
- Tighten up parsing of the inital line by follow recommentation of RFC7230
|
||||
- Restrict separators to OWS for http headers
|
||||
- Add unit test
|
||||
|
||||
Result:
|
||||
|
||||
Stricter parsing of HTTP1
|
||||
---
|
||||
.../handler/codec/http/HttpObjectDecoder.java | 63 ++++++++++++++-----
|
||||
.../codec/http/HttpRequestDecoderTest.java | 25 +++++++-
|
||||
.../codec/http/HttpResponseDecoderTest.java | 2 +-
|
||||
.../util/internal/AppendableCharSequence.java | 7 +++
|
||||
4 files changed, 80 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/HttpObjectDecoder.java b/codec-http/src/main/java/io/netty/handler/codec/http/HttpObjectDecoder.java
|
||||
index 82b0c36..b4de681 100644
|
||||
--- a/codec-http/src/main/java/io/netty/handler/codec/http/HttpObjectDecoder.java
|
||||
+++ b/codec-http/src/main/java/io/netty/handler/codec/http/HttpObjectDecoder.java
|
||||
@@ -773,13 +773,13 @@ public abstract class HttpObjectDecoder extends ByteToMessageDecoder {
|
||||
int cStart;
|
||||
int cEnd;
|
||||
|
||||
- aStart = findNonWhitespace(sb, 0);
|
||||
- aEnd = findWhitespace(sb, aStart);
|
||||
+ aStart = findNonSPLenient(sb, 0);
|
||||
+ aEnd = findSPLenient(sb, aStart);
|
||||
|
||||
- bStart = findNonWhitespace(sb, aEnd);
|
||||
- bEnd = findWhitespace(sb, bStart);
|
||||
+ bStart = findNonSPLenient(sb, aEnd);
|
||||
+ bEnd = findSPLenient(sb, bStart);
|
||||
|
||||
- cStart = findNonWhitespace(sb, bEnd);
|
||||
+ cStart = findNonSPLenient(sb, bEnd);
|
||||
cEnd = findEndOfString(sb);
|
||||
|
||||
return new String[] {
|
||||
@@ -796,7 +796,7 @@ public abstract class HttpObjectDecoder extends ByteToMessageDecoder {
|
||||
int valueStart;
|
||||
int valueEnd;
|
||||
|
||||
- nameStart = findNonWhitespace(sb, 0);
|
||||
+ nameStart = findNonWhitespace(sb, 0, false);
|
||||
for (nameEnd = nameStart; nameEnd < length; nameEnd ++) {
|
||||
char ch = sb.charAt(nameEnd);
|
||||
// https://tools.ietf.org/html/rfc7230#section-3.2.4
|
||||
@@ -813,7 +813,7 @@ public abstract class HttpObjectDecoder extends ByteToMessageDecoder {
|
||||
// is done in the DefaultHttpHeaders implementation.
|
||||
//
|
||||
// In the case of decoding a response we will "skip" the whitespace.
|
||||
- (!isDecodingRequest() && Character.isWhitespace(ch))) {
|
||||
+ (!isDecodingRequest() && isOWS(ch))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -831,7 +831,7 @@ public abstract class HttpObjectDecoder extends ByteToMessageDecoder {
|
||||
}
|
||||
|
||||
name = sb.subStringUnsafe(nameStart, nameEnd);
|
||||
- valueStart = findNonWhitespace(sb, colonEnd);
|
||||
+ valueStart = findNonWhitespace(sb, colonEnd, true);
|
||||
if (valueStart == length) {
|
||||
value = EMPTY_VALUE;
|
||||
} else {
|
||||
@@ -840,19 +840,45 @@ public abstract class HttpObjectDecoder extends ByteToMessageDecoder {
|
||||
}
|
||||
}
|
||||
|
||||
- private static int findNonWhitespace(AppendableCharSequence sb, int offset) {
|
||||
+ private static int findNonSPLenient(AppendableCharSequence sb, int offset) {
|
||||
for (int result = offset; result < sb.length(); ++result) {
|
||||
- if (!Character.isWhitespace(sb.charAtUnsafe(result))) {
|
||||
+ char c = sb.charAtUnsafe(result);
|
||||
+ // See https://tools.ietf.org/html/rfc7230#section-3.5
|
||||
+ if (isSPLenient(c)) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ if (Character.isWhitespace(c)) {
|
||||
+ // Any other whitespace delimiter is invalid
|
||||
+ throw new IllegalArgumentException("Invalid separator");
|
||||
+ }
|
||||
+ return result;
|
||||
+ }
|
||||
+ return sb.length();
|
||||
+ }
|
||||
+
|
||||
+ private static int findSPLenient(AppendableCharSequence sb, int offset) {
|
||||
+ for (int result = offset; result < sb.length(); ++result) {
|
||||
+ if (isSPLenient(sb.charAtUnsafe(result))) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return sb.length();
|
||||
}
|
||||
|
||||
- private static int findWhitespace(AppendableCharSequence sb, int offset) {
|
||||
+ private static boolean isSPLenient(char c) {
|
||||
+ // See https://tools.ietf.org/html/rfc7230#section-3.5
|
||||
+ return c == ' ' || c == (char) 0x09 || c == (char) 0x0B || c == (char) 0x0C || c == (char) 0x0D;
|
||||
+ }
|
||||
+
|
||||
+ private static int findNonWhitespace(AppendableCharSequence sb, int offset, boolean validateOWS) {
|
||||
for (int result = offset; result < sb.length(); ++result) {
|
||||
- if (Character.isWhitespace(sb.charAtUnsafe(result))) {
|
||||
+ char c = sb.charAtUnsafe(result);
|
||||
+ if (!Character.isWhitespace(c)) {
|
||||
return result;
|
||||
+ } else if (validateOWS && !isOWS(c)) {
|
||||
+ // Only OWS is supported for whitespace
|
||||
+ throw new IllegalArgumentException("Invalid separator, only a single space or horizontal tab allowed," +
|
||||
+ " but received a '" + c + "'");
|
||||
}
|
||||
}
|
||||
return sb.length();
|
||||
@@ -867,6 +893,10 @@ public abstract class HttpObjectDecoder extends ByteToMessageDecoder {
|
||||
return 0;
|
||||
}
|
||||
|
||||
+ private static boolean isOWS(char ch) {
|
||||
+ return ch == ' ' || ch == (char) 0x09;
|
||||
+ }
|
||||
+
|
||||
private static class HeaderParser implements ByteProcessor {
|
||||
private final AppendableCharSequence seq;
|
||||
private final int maxLength;
|
||||
@@ -896,10 +926,13 @@ public abstract class HttpObjectDecoder extends ByteToMessageDecoder {
|
||||
@Override
|
||||
public boolean process(byte value) throws Exception {
|
||||
char nextByte = (char) (value & 0xFF);
|
||||
- if (nextByte == HttpConstants.CR) {
|
||||
- return true;
|
||||
- }
|
||||
if (nextByte == HttpConstants.LF) {
|
||||
+ int len = seq.length();
|
||||
+ // Drop CR if we had a CRLF pair
|
||||
+ if (len >= 1 && seq.charAtUnsafe(len - 1) == HttpConstants.CR) {
|
||||
+ -- size;
|
||||
+ seq.setLength(len - 1);
|
||||
+ }
|
||||
return false;
|
||||
}
|
||||
|
||||
diff --git a/codec-http/src/test/java/io/netty/handler/codec/http/HttpRequestDecoderTest.java b/codec-http/src/test/java/io/netty/handler/codec/http/HttpRequestDecoderTest.java
|
||||
index 000bd0c..902b379 100644
|
||||
--- a/codec-http/src/test/java/io/netty/handler/codec/http/HttpRequestDecoderTest.java
|
||||
+++ b/codec-http/src/test/java/io/netty/handler/codec/http/HttpRequestDecoderTest.java
|
||||
@@ -373,6 +373,30 @@ public class HttpRequestDecoderTest {
|
||||
testInvalidHeaders0(requestStr);
|
||||
}
|
||||
|
||||
+ @Test
|
||||
+ public void testContentLengthAndTransferEncodingHeadersWithVerticalTab() {
|
||||
+ testContentLengthAndTransferEncodingHeadersWithInvalidSeparator((char) 0x0b, false);
|
||||
+ testContentLengthAndTransferEncodingHeadersWithInvalidSeparator((char) 0x0b, true);
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void testContentLengthAndTransferEncodingHeadersWithCR() {
|
||||
+ testContentLengthAndTransferEncodingHeadersWithInvalidSeparator((char) 0x0d, false);
|
||||
+ testContentLengthAndTransferEncodingHeadersWithInvalidSeparator((char) 0x0d, true);
|
||||
+ }
|
||||
+
|
||||
+ private static void testContentLengthAndTransferEncodingHeadersWithInvalidSeparator(
|
||||
+ char separator, boolean extraLine) {
|
||||
+ String requestStr = "POST / HTTP/1.1\r\n" +
|
||||
+ "Host: example.com\r\n" +
|
||||
+ "Connection: close\r\n" +
|
||||
+ "Content-Length: 9\r\n" +
|
||||
+ "Transfer-Encoding:" + separator + "chunked\r\n\r\n" +
|
||||
+ (extraLine ? "0\r\n\r\n" : "") +
|
||||
+ "something\r\n\r\n";
|
||||
+ testInvalidHeaders0(requestStr);
|
||||
+ }
|
||||
+
|
||||
@Test
|
||||
public void testContentLengthHeaderAndChunked() {
|
||||
String requestStr = "POST / HTTP/1.1\r\n" +
|
||||
@@ -381,7 +405,6 @@ public class HttpRequestDecoderTest {
|
||||
"Content-Length: 5\r\n" +
|
||||
"Transfer-Encoding: chunked\r\n\r\n" +
|
||||
"0\r\n\r\n";
|
||||
-
|
||||
EmbeddedChannel channel = new EmbeddedChannel(new HttpRequestDecoder());
|
||||
assertTrue(channel.writeInbound(Unpooled.copiedBuffer(requestStr, CharsetUtil.US_ASCII)));
|
||||
HttpRequest request = channel.readInbound();
|
||||
diff --git a/codec-http/src/test/java/io/netty/handler/codec/http/HttpResponseDecoderTest.java b/codec-http/src/test/java/io/netty/handler/codec/http/HttpResponseDecoderTest.java
|
||||
index d67b3ad..66cefc9 100644
|
||||
--- a/codec-http/src/test/java/io/netty/handler/codec/http/HttpResponseDecoderTest.java
|
||||
+++ b/codec-http/src/test/java/io/netty/handler/codec/http/HttpResponseDecoderTest.java
|
||||
@@ -50,7 +50,7 @@ public class HttpResponseDecoderTest {
|
||||
final int maxHeaderSize = 8192;
|
||||
|
||||
final EmbeddedChannel ch = new EmbeddedChannel(new HttpResponseDecoder(4096, maxHeaderSize, 8192));
|
||||
- final char[] bytes = new char[maxHeaderSize / 2 - 2];
|
||||
+ final char[] bytes = new char[maxHeaderSize / 2 - 4];
|
||||
Arrays.fill(bytes, 'a');
|
||||
|
||||
ch.writeInbound(Unpooled.copiedBuffer("HTTP/1.1 200 OK\r\n", CharsetUtil.US_ASCII));
|
||||
diff --git a/common/src/main/java/io/netty/util/internal/AppendableCharSequence.java b/common/src/main/java/io/netty/util/internal/AppendableCharSequence.java
|
||||
index 408c32f..bf1eee5 100644
|
||||
--- a/common/src/main/java/io/netty/util/internal/AppendableCharSequence.java
|
||||
+++ b/common/src/main/java/io/netty/util/internal/AppendableCharSequence.java
|
||||
@@ -37,6 +37,13 @@ public final class AppendableCharSequence implements CharSequence, Appendable {
|
||||
pos = chars.length;
|
||||
}
|
||||
|
||||
+ public void setLength(int length) {
|
||||
+ if (length < 0 || length > pos) {
|
||||
+ throw new IllegalArgumentException("length: " + length + " (length: >= 0, <= " + pos + ')');
|
||||
+ }
|
||||
+ this.pos = length;
|
||||
+ }
|
||||
+
|
||||
@Override
|
||||
public int length() {
|
||||
return pos;
|
||||
--
|
||||
2.27.0
|
||||
|
||||
312
CVE-2021-43797.patch
Normal file
312
CVE-2021-43797.patch
Normal file
@ -0,0 +1,312 @@
|
||||
From 2d941652f20135719b9ae5f4a373328ce5379970 Mon Sep 17 00:00:00 2001
|
||||
From: Norman Maurer <norman_maurer@apple.com>
|
||||
Date: Thu, 9 Dec 2021 14:49:43 +0100
|
||||
Subject: [PATCH] Merge pull request from GHSA-wx5j-54mm-rqqq
|
||||
|
||||
Motivation:
|
||||
|
||||
We should validate that only OWS is allowed before / after a header name and otherwise throw. At the moment we just "strip" everything except OWS.
|
||||
|
||||
Modifications:
|
||||
|
||||
- Adjust code to correctly validate
|
||||
- Add unit tests
|
||||
|
||||
Result:
|
||||
|
||||
More strict and correct behaviour
|
||||
---
|
||||
.../codec/http/DefaultHttpHeaders.java | 8 ++
|
||||
.../handler/codec/http/HttpObjectDecoder.java | 8 +-
|
||||
.../codec/http/HttpRequestDecoderTest.java | 87 +++++++++++++++++--
|
||||
.../codec/http/HttpResponseDecoderTest.java | 78 +++++++++++++++++
|
||||
4 files changed, 171 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/DefaultHttpHeaders.java b/codec-http/src/main/java/io/netty/handler/codec/http/DefaultHttpHeaders.java
|
||||
index d18f196..35dd88e 100644
|
||||
--- a/codec-http/src/main/java/io/netty/handler/codec/http/DefaultHttpHeaders.java
|
||||
+++ b/codec-http/src/main/java/io/netty/handler/codec/http/DefaultHttpHeaders.java
|
||||
@@ -324,6 +324,10 @@ public class DefaultHttpHeaders extends HttpHeaders {
|
||||
|
||||
private static void validateHeaderNameElement(byte value) {
|
||||
switch (value) {
|
||||
+ case 0x1c:
|
||||
+ case 0x1d:
|
||||
+ case 0x1e:
|
||||
+ case 0x1f:
|
||||
case 0x00:
|
||||
case '\t':
|
||||
case '\n':
|
||||
@@ -348,6 +352,10 @@ public class DefaultHttpHeaders extends HttpHeaders {
|
||||
|
||||
private static void validateHeaderNameElement(char value) {
|
||||
switch (value) {
|
||||
+ case 0x1c:
|
||||
+ case 0x1d:
|
||||
+ case 0x1e:
|
||||
+ case 0x1f:
|
||||
case 0x00:
|
||||
case '\t':
|
||||
case '\n':
|
||||
diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/HttpObjectDecoder.java b/codec-http/src/main/java/io/netty/handler/codec/http/HttpObjectDecoder.java
|
||||
index b4de681..15e86a5 100644
|
||||
--- a/codec-http/src/main/java/io/netty/handler/codec/http/HttpObjectDecoder.java
|
||||
+++ b/codec-http/src/main/java/io/netty/handler/codec/http/HttpObjectDecoder.java
|
||||
@@ -796,7 +796,7 @@ public abstract class HttpObjectDecoder extends ByteToMessageDecoder {
|
||||
int valueStart;
|
||||
int valueEnd;
|
||||
|
||||
- nameStart = findNonWhitespace(sb, 0, false);
|
||||
+ nameStart = findNonWhitespace(sb, 0);
|
||||
for (nameEnd = nameStart; nameEnd < length; nameEnd ++) {
|
||||
char ch = sb.charAt(nameEnd);
|
||||
// https://tools.ietf.org/html/rfc7230#section-3.2.4
|
||||
@@ -831,7 +831,7 @@ public abstract class HttpObjectDecoder extends ByteToMessageDecoder {
|
||||
}
|
||||
|
||||
name = sb.subStringUnsafe(nameStart, nameEnd);
|
||||
- valueStart = findNonWhitespace(sb, colonEnd, true);
|
||||
+ valueStart = findNonWhitespace(sb, colonEnd);
|
||||
if (valueStart == length) {
|
||||
value = EMPTY_VALUE;
|
||||
} else {
|
||||
@@ -870,12 +870,12 @@ public abstract class HttpObjectDecoder extends ByteToMessageDecoder {
|
||||
return c == ' ' || c == (char) 0x09 || c == (char) 0x0B || c == (char) 0x0C || c == (char) 0x0D;
|
||||
}
|
||||
|
||||
- private static int findNonWhitespace(AppendableCharSequence sb, int offset, boolean validateOWS) {
|
||||
+ private static int findNonWhitespace(AppendableCharSequence sb, int offset) {
|
||||
for (int result = offset; result < sb.length(); ++result) {
|
||||
char c = sb.charAtUnsafe(result);
|
||||
if (!Character.isWhitespace(c)) {
|
||||
return result;
|
||||
- } else if (validateOWS && !isOWS(c)) {
|
||||
+ } else if (!isOWS(c)) {
|
||||
// Only OWS is supported for whitespace
|
||||
throw new IllegalArgumentException("Invalid separator, only a single space or horizontal tab allowed," +
|
||||
" but received a '" + c + "'");
|
||||
diff --git a/codec-http/src/test/java/io/netty/handler/codec/http/HttpRequestDecoderTest.java b/codec-http/src/test/java/io/netty/handler/codec/http/HttpRequestDecoderTest.java
|
||||
index 902b379..fc7cfb4 100644
|
||||
--- a/codec-http/src/test/java/io/netty/handler/codec/http/HttpRequestDecoderTest.java
|
||||
+++ b/codec-http/src/test/java/io/netty/handler/codec/http/HttpRequestDecoderTest.java
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package io.netty.handler.codec.http;
|
||||
|
||||
+import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.embedded.EmbeddedChannel;
|
||||
import io.netty.util.AsciiString;
|
||||
@@ -294,6 +295,75 @@ public class HttpRequestDecoderTest {
|
||||
assertFalse(channel.finishAndReleaseAll());
|
||||
}
|
||||
|
||||
+ @Test
|
||||
+ public void testHeaderNameStartsWithControlChar1c() {
|
||||
+ testHeaderNameStartsWithControlChar(0x1c);
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void testHeaderNameStartsWithControlChar1d() {
|
||||
+ testHeaderNameStartsWithControlChar(0x1d);
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void testHeaderNameStartsWithControlChar1e() {
|
||||
+ testHeaderNameStartsWithControlChar(0x1e);
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void testHeaderNameStartsWithControlChar1f() {
|
||||
+ testHeaderNameStartsWithControlChar(0x1f);
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void testHeaderNameStartsWithControlChar0c() {
|
||||
+ testHeaderNameStartsWithControlChar(0x0c);
|
||||
+ }
|
||||
+
|
||||
+ private void testHeaderNameStartsWithControlChar(int controlChar) {
|
||||
+ ByteBuf requestBuffer = Unpooled.buffer();
|
||||
+ requestBuffer.writeCharSequence("GET /some/path HTTP/1.1\r\n" +
|
||||
+ "Host: netty.io\r\n", CharsetUtil.US_ASCII);
|
||||
+ requestBuffer.writeByte(controlChar);
|
||||
+ requestBuffer.writeCharSequence("Transfer-Encoding: chunked\r\n\r\n", CharsetUtil.US_ASCII);
|
||||
+ testInvalidHeaders0(requestBuffer);
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void testHeaderNameEndsWithControlChar1c() {
|
||||
+ testHeaderNameEndsWithControlChar(0x1c);
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void testHeaderNameEndsWithControlChar1d() {
|
||||
+ testHeaderNameEndsWithControlChar(0x1d);
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void testHeaderNameEndsWithControlChar1e() {
|
||||
+ testHeaderNameEndsWithControlChar(0x1e);
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void testHeaderNameEndsWithControlChar1f() {
|
||||
+ testHeaderNameEndsWithControlChar(0x1f);
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void testHeaderNameEndsWithControlChar0c() {
|
||||
+ testHeaderNameEndsWithControlChar(0x0c);
|
||||
+ }
|
||||
+
|
||||
+ private void testHeaderNameEndsWithControlChar(int controlChar) {
|
||||
+ ByteBuf requestBuffer = Unpooled.buffer();
|
||||
+ requestBuffer.writeCharSequence("GET /some/path HTTP/1.1\r\n" +
|
||||
+ "Host: netty.io\r\n", CharsetUtil.US_ASCII);
|
||||
+ requestBuffer.writeCharSequence("Transfer-Encoding", CharsetUtil.US_ASCII);
|
||||
+ requestBuffer.writeByte(controlChar);
|
||||
+ requestBuffer.writeCharSequence(": chunked\r\n\r\n", CharsetUtil.US_ASCII);
|
||||
+ testInvalidHeaders0(requestBuffer);
|
||||
+ }
|
||||
+
|
||||
@Test
|
||||
public void testWhitespace() {
|
||||
String requestStr = "GET /some/path HTTP/1.1\r\n" +
|
||||
@@ -303,9 +373,9 @@ public class HttpRequestDecoderTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
- public void testWhitespaceBeforeTransferEncoding01() {
|
||||
+ public void testWhitespaceInTransferEncoding01() {
|
||||
String requestStr = "GET /some/path HTTP/1.1\r\n" +
|
||||
- " Transfer-Encoding : chunked\r\n" +
|
||||
+ "Transfer-Encoding : chunked\r\n" +
|
||||
"Content-Length: 1\r\n" +
|
||||
"Host: netty.io\r\n\r\n" +
|
||||
"a";
|
||||
@@ -313,9 +383,9 @@ public class HttpRequestDecoderTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
- public void testWhitespaceBeforeTransferEncoding02() {
|
||||
+ public void testWhitespaceInTransferEncoding02() {
|
||||
String requestStr = "POST / HTTP/1.1" +
|
||||
- " Transfer-Encoding : chunked\r\n" +
|
||||
+ "Transfer-Encoding : chunked\r\n" +
|
||||
"Host: target.com" +
|
||||
"Content-Length: 65\r\n\r\n" +
|
||||
"0\r\n\r\n" +
|
||||
@@ -412,15 +482,20 @@ public class HttpRequestDecoderTest {
|
||||
assertTrue(request.headers().contains("Transfer-Encoding", "chunked", false));
|
||||
assertFalse(request.headers().contains("Content-Length"));
|
||||
LastHttpContent c = channel.readInbound();
|
||||
+ c.release();
|
||||
assertFalse(channel.finish());
|
||||
}
|
||||
|
||||
private static void testInvalidHeaders0(String requestStr) {
|
||||
+ testInvalidHeaders0(Unpooled.copiedBuffer(requestStr, CharsetUtil.US_ASCII));
|
||||
+ }
|
||||
+
|
||||
+ private static void testInvalidHeaders0(ByteBuf requestBuffer) {
|
||||
EmbeddedChannel channel = new EmbeddedChannel(new HttpRequestDecoder());
|
||||
- assertTrue(channel.writeInbound(Unpooled.copiedBuffer(requestStr, CharsetUtil.US_ASCII)));
|
||||
+ assertTrue(channel.writeInbound(requestBuffer));
|
||||
HttpRequest request = channel.readInbound();
|
||||
+ assertThat(request.decoderResult().cause(), instanceOf(IllegalArgumentException.class));
|
||||
assertTrue(request.decoderResult().isFailure());
|
||||
- assertTrue(request.decoderResult().cause() instanceof IllegalArgumentException);
|
||||
assertFalse(channel.finish());
|
||||
}
|
||||
}
|
||||
diff --git a/codec-http/src/test/java/io/netty/handler/codec/http/HttpResponseDecoderTest.java b/codec-http/src/test/java/io/netty/handler/codec/http/HttpResponseDecoderTest.java
|
||||
index 66cefc9..df44293 100644
|
||||
--- a/codec-http/src/test/java/io/netty/handler/codec/http/HttpResponseDecoderTest.java
|
||||
+++ b/codec-http/src/test/java/io/netty/handler/codec/http/HttpResponseDecoderTest.java
|
||||
@@ -676,4 +676,82 @@ public class HttpResponseDecoderTest {
|
||||
assertEquals("netty.io", response.headers().get(HttpHeaderNames.HOST));
|
||||
assertFalse(channel.finish());
|
||||
}
|
||||
+
|
||||
+ @Test
|
||||
+ public void testHeaderNameStartsWithControlChar1c() {
|
||||
+ testHeaderNameStartsWithControlChar(0x1c);
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void testHeaderNameStartsWithControlChar1d() {
|
||||
+ testHeaderNameStartsWithControlChar(0x1d);
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void testHeaderNameStartsWithControlChar1e() {
|
||||
+ testHeaderNameStartsWithControlChar(0x1e);
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void testHeaderNameStartsWithControlChar1f() {
|
||||
+ testHeaderNameStartsWithControlChar(0x1f);
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void testHeaderNameStartsWithControlChar0c() {
|
||||
+ testHeaderNameStartsWithControlChar(0x0c);
|
||||
+ }
|
||||
+
|
||||
+ private void testHeaderNameStartsWithControlChar(int controlChar) {
|
||||
+ ByteBuf responseBuffer = Unpooled.buffer();
|
||||
+ responseBuffer.writeCharSequence("HTTP/1.1 200 OK\r\n" +
|
||||
+ "Host: netty.io\r\n", CharsetUtil.US_ASCII);
|
||||
+ responseBuffer.writeByte(controlChar);
|
||||
+ responseBuffer.writeCharSequence("Transfer-Encoding: chunked\r\n\r\n", CharsetUtil.US_ASCII);
|
||||
+ testInvalidHeaders0(responseBuffer);
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void testHeaderNameEndsWithControlChar1c() {
|
||||
+ testHeaderNameEndsWithControlChar(0x1c);
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void testHeaderNameEndsWithControlChar1d() {
|
||||
+ testHeaderNameEndsWithControlChar(0x1d);
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void testHeaderNameEndsWithControlChar1e() {
|
||||
+ testHeaderNameEndsWithControlChar(0x1e);
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void testHeaderNameEndsWithControlChar1f() {
|
||||
+ testHeaderNameEndsWithControlChar(0x1f);
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void testHeaderNameEndsWithControlChar0c() {
|
||||
+ testHeaderNameEndsWithControlChar(0x0c);
|
||||
+ }
|
||||
+
|
||||
+ private void testHeaderNameEndsWithControlChar(int controlChar) {
|
||||
+ ByteBuf responseBuffer = Unpooled.buffer();
|
||||
+ responseBuffer.writeCharSequence("HTTP/1.1 200 OK\r\n" +
|
||||
+ "Host: netty.io\r\n", CharsetUtil.US_ASCII);
|
||||
+ responseBuffer.writeCharSequence("Transfer-Encoding", CharsetUtil.US_ASCII);
|
||||
+ responseBuffer.writeByte(controlChar);
|
||||
+ responseBuffer.writeCharSequence(": chunked\r\n\r\n", CharsetUtil.US_ASCII);
|
||||
+ testInvalidHeaders0(responseBuffer);
|
||||
+ }
|
||||
+
|
||||
+ private static void testInvalidHeaders0(ByteBuf responseBuffer) {
|
||||
+ EmbeddedChannel channel = new EmbeddedChannel(new HttpResponseDecoder());
|
||||
+ assertTrue(channel.writeInbound(responseBuffer));
|
||||
+ HttpResponse response = channel.readInbound();
|
||||
+ assertThat(response.decoderResult().cause(), instanceOf(IllegalArgumentException.class));
|
||||
+ assertTrue(response.decoderResult().isFailure());
|
||||
+ assertFalse(channel.finish());
|
||||
+ }
|
||||
}
|
||||
--
|
||||
2.27.0
|
||||
|
||||
12
netty.spec
12
netty.spec
@ -2,7 +2,7 @@
|
||||
|
||||
Name: netty
|
||||
Version: 4.1.13
|
||||
Release: 14
|
||||
Release: 15
|
||||
Summary: Asynchronous event-driven network application Java framework
|
||||
License: ASL 2.0
|
||||
URL: https://netty.io/
|
||||
@ -27,6 +27,8 @@ Patch0015: CVE-2021-21409.patch
|
||||
Patch0016: fix-build-error.patch
|
||||
Patch0017: CVE-2021-37136.patch
|
||||
Patch0018: CVE-2021-37137.patch
|
||||
Patch0019: CVE-2021-43797-pre.patch
|
||||
Patch0020: CVE-2021-43797.patch
|
||||
|
||||
BuildRequires: maven-local mvn(ant-contrib:ant-contrib)
|
||||
BuildRequires: mvn(com.jcraft:jzlib) mvn(commons-logging:commons-logging)
|
||||
@ -38,7 +40,7 @@ BuildRequires: mvn(org.fusesource.hawtjni:maven-hawtjni-plugin) mvn(org.javas
|
||||
BuildRequires: mvn(org.jctools:jctools-core) mvn(org.slf4j:slf4j-api)
|
||||
BuildRequires: mvn(org.sonatype.oss:oss-parent:pom:)
|
||||
BuildRequires: mvn(com.fasterxml:aalto-xml)
|
||||
BuildRequires: mvn(com.ning:compress-lzf) mvn(net.jpountz.lz4:lz4)
|
||||
BuildRequires: mvn(com.ning:compress-lzf)
|
||||
BuildRequires: mvn(org.apache.logging.log4j:log4j-api) mvn(org.bouncycastle:bcpkix-jdk15on)
|
||||
BuildRequires: mvn(org.jboss.marshalling:jboss-marshalling) mvn(org.eclipse.jetty.alpn:alpn-api)
|
||||
|
||||
@ -131,6 +133,9 @@ sed -i 's|taskdef|taskdef classpathref="maven.plugin.classpath"|' all/pom.xml
|
||||
rm -f codec/src/main/java/io/netty/handler/codec/compression/LzmaFrameEncoder.java
|
||||
rm -f codec/src/test/java/io/netty/handler/codec/compression/LzmaFrameEncoderTest.java
|
||||
|
||||
%pom_remove_dep -r net.jpountz.lz4:lz4
|
||||
rm -f codec/src/*/java/io/netty/handler/codec/compression/Lz4*.java
|
||||
|
||||
%build
|
||||
export CFLAGS="$RPM_OPT_FLAGS" LDFLAGS="$RPM_LD_FLAGS"
|
||||
%mvn_build -f
|
||||
@ -148,6 +153,9 @@ export CFLAGS="$RPM_OPT_FLAGS" LDFLAGS="$RPM_LD_FLAGS"
|
||||
|
||||
|
||||
%changelog
|
||||
* Fri Apr 22 2022 wangkai <wangkai385@h-partners.com> - 4.1.13-15
|
||||
- Remove lz4-java dependency and fix CVE-2021-43797
|
||||
|
||||
* Wed Oct 27 2021 wangkai <wangkai385@huawei.com> - 4.1.13-14
|
||||
- fix CVE-2021-37136 CVE-2021-37137
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user