115 lines
5.2 KiB
Diff
115 lines
5.2 KiB
Diff
From 902356dc34097b50eb6ca3a74443be466e991a77 Mon Sep 17 00:00:00 2001
|
|
From: wangxiao65 <287608437@qq.com>
|
|
Date: Wed, 2 Dec 2020 11:07:21 +0800
|
|
Subject: [PATCH] CVE-2020-13943
|
|
|
|
---
|
|
java/org/apache/coyote/http2/Http2Parser.java | 2 +-
|
|
.../coyote/http2/Http2UpgradeHandler.java | 20 ++++++++++++-------
|
|
.../coyote/http2/TestHttp2Section_5_1.java | 20 ++++++++++++-------
|
|
3 files changed, 27 insertions(+), 15 deletions(-)
|
|
|
|
diff --git a/java/org/apache/coyote/http2/Http2Parser.java b/java/org/apache/coyote/http2/Http2Parser.java
|
|
index f5e19865b2..6ec659d1e0 100644
|
|
--- a/java/org/apache/coyote/http2/Http2Parser.java
|
|
+++ b/java/org/apache/coyote/http2/Http2Parser.java
|
|
@@ -721,7 +721,7 @@ class Http2Parser {
|
|
// Header frames
|
|
HeaderEmitter headersStart(int streamId, boolean headersEndStream)
|
|
throws Http2Exception, IOException;
|
|
- void headersEnd(int streamId) throws ConnectionException;
|
|
+ void headersEnd(int streamId) throws Http2Exception;
|
|
|
|
// Priority frames (also headers)
|
|
void reprioritise(int streamId, int parentStreamId, boolean exclusive, int weight)
|
|
diff --git a/java/org/apache/coyote/http2/Http2UpgradeHandler.java b/java/org/apache/coyote/http2/Http2UpgradeHandler.java
|
|
index 9c18bf0ca8..af10cd0838 100644
|
|
--- a/java/org/apache/coyote/http2/Http2UpgradeHandler.java
|
|
+++ b/java/org/apache/coyote/http2/Http2UpgradeHandler.java
|
|
@@ -1386,12 +1386,6 @@ class Http2UpgradeHandler extends AbstractStream implements InternalHttpUpgradeH
|
|
stream.checkState(FrameType.HEADERS);
|
|
stream.receivedStartOfHeaders(headersEndStream);
|
|
closeIdleStreams(streamId);
|
|
- if (localSettings.getMaxConcurrentStreams() < activeRemoteStreamCount.incrementAndGet()) {
|
|
- setConnectionTimeoutForStreamCount(activeRemoteStreamCount.decrementAndGet());
|
|
- throw new StreamException(sm.getString("upgradeHandler.tooManyRemoteStreams",
|
|
- Long.toString(localSettings.getMaxConcurrentStreams())),
|
|
- Http2Error.REFUSED_STREAM, streamId);
|
|
- }
|
|
return stream;
|
|
} else {
|
|
if (log.isDebugEnabled()) {
|
|
@@ -1439,12 +1433,24 @@ class Http2UpgradeHandler extends AbstractStream implements InternalHttpUpgradeH
|
|
|
|
|
|
@Override
|
|
- public void headersEnd(int streamId) throws ConnectionException {
|
|
+ public void headersEnd(int streamId) throws Http2Exception {
|
|
Stream stream = getStream(streamId, connectionState.get().isNewStreamAllowed());
|
|
if (stream != null) {
|
|
setMaxProcessedStream(streamId);
|
|
if (stream.isActive()) {
|
|
if (stream.receivedEndOfHeaders()) {
|
|
+
|
|
+ if (localSettings.getMaxConcurrentStreams() < activeRemoteStreamCount.incrementAndGet()) {
|
|
+ setConnectionTimeoutForStreamCount(activeRemoteStreamCount.decrementAndGet());
|
|
+ // Ignoring maxConcurrentStreams increases the overhead count
|
|
+ increaseOverheadCount();
|
|
+ throw new StreamException(sm.getString("upgradeHandler.tooManyRemoteStreams",
|
|
+ Long.toString(localSettings.getMaxConcurrentStreams())),
|
|
+ Http2Error.REFUSED_STREAM, streamId);
|
|
+ }
|
|
+ // Valid new stream reduces the overhead count
|
|
+ reduceOverheadCount();
|
|
+
|
|
processStreamOnContainerThread(stream);
|
|
}
|
|
}
|
|
diff --git a/test/org/apache/coyote/http2/TestHttp2Section_5_1.java b/test/org/apache/coyote/http2/TestHttp2Section_5_1.java
|
|
index f878653ecf..0b937a9fb9 100644
|
|
--- a/test/org/apache/coyote/http2/TestHttp2Section_5_1.java
|
|
+++ b/test/org/apache/coyote/http2/TestHttp2Section_5_1.java
|
|
@@ -222,11 +222,11 @@ public class TestHttp2Section_5_1 extends Http2TestBase {
|
|
// Expecting
|
|
// 1 * headers
|
|
// 56k-1 of body (7 * ~8k)
|
|
- // 1 * error (could be in any order)
|
|
- for (int i = 0; i < 8; i++) {
|
|
+ // 1 * error
|
|
+ // for a total of 9 frames (could be in any order)
|
|
+ for (int i = 0; i < 9; i++) {
|
|
parser.readFrame(true);
|
|
}
|
|
- parser.readFrame(true);
|
|
|
|
Assert.assertTrue(output.getTrace(),
|
|
output.getTrace().contains("5-RST-[" +
|
|
@@ -238,14 +238,20 @@ public class TestHttp2Section_5_1 extends Http2TestBase {
|
|
|
|
// Release the remaining body
|
|
sendWindowUpdate(0, (1 << 31) - 2);
|
|
- // Allow for the 8k still in the stream window
|
|
+ // Allow for the ~8k still in the stream window
|
|
sendWindowUpdate(3, (1 << 31) - 8193);
|
|
|
|
- // 192k of body (24 * 8k)
|
|
- // 1 * error (could be in any order)
|
|
- for (int i = 0; i < 24; i++) {
|
|
+ // Read until the end of stream 3
|
|
+ while (!output.getTrace().contains("3-EndOfStream")) {
|
|
parser.readFrame(true);
|
|
}
|
|
+ output.clearTrace();
|
|
+
|
|
+ // Confirm another request can be sent once concurrency falls back below limit
|
|
+ sendSimpleGetRequest(7);
|
|
+ parser.readFrame(true);
|
|
+ parser.readFrame(true);
|
|
+ Assert.assertEquals(getSimpleResponseTrace(7), output.getTrace());
|
|
}
|
|
|
|
|
|
--
|
|
2.23.0
|
|
|