!17 Update to 9.1.2 fox fix CVE-2021-44040
From: @wk333 Reviewed-by: @seuzw Signed-off-by: @seuzw
This commit is contained in:
commit
1387dcf8ae
@ -1,33 +0,0 @@
|
||||
From 64f25678bfbbd1433cce703e3c43bcc49a53de56 Mon Sep 17 00:00:00 2001
|
||||
From: Brian Neradt <brian.neradt@verizonmedia.com>
|
||||
Date: Wed, 27 Oct 2021 13:35:41 -0500
|
||||
Subject: [PATCH] Fix output '\n' HTTP field line endings (#8455)
|
||||
|
||||
This is another attempt to fix what was initially addressed in #8096 but
|
||||
got backed out via #8305. That more extensive patch was considered too
|
||||
invasive and potentially risky. This more targeted patch will fix
|
||||
clients that only send the \n endings but it will force the \r\n line
|
||||
ending on output.
|
||||
|
||||
This was mostly in place except for header lines that get
|
||||
m_n_v_raw_printable set, which seems to be most header lines. The
|
||||
addition checks to see if the header line ends in \r\n. If it does not
|
||||
the m_n_v_raw_printable flag gets cleared and the logic that explicitly
|
||||
adds the line endings while be invoked on output.
|
||||
---
|
||||
proxy/hdrs/MIME.cc | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/proxy/hdrs/MIME.cc b/proxy/hdrs/MIME.cc
|
||||
index 14e7ce352a6..729ec9da977 100644
|
||||
--- a/proxy/hdrs/MIME.cc
|
||||
+++ b/proxy/hdrs/MIME.cc
|
||||
@@ -2580,6 +2580,8 @@ mime_parser_parse(MIMEParser *parser, HdrHeap *heap, MIMEHdrImpl *mh, const char
|
||||
}
|
||||
field_name.rtrim_if(&ParseRules::is_ws);
|
||||
raw_print_field = false;
|
||||
+ } else if (parsed.suffix(2) != "\r\n") {
|
||||
+ raw_print_field = false;
|
||||
}
|
||||
|
||||
// find value first
|
||||
@ -1,467 +0,0 @@
|
||||
From 83c89f3d217d473ecb000b68c910c0f183c3a355 Mon Sep 17 00:00:00 2001
|
||||
From: Brian Neradt <brian.neradt@gmail.com>
|
||||
Date: Wed, 27 Oct 2021 11:30:54 -0500
|
||||
Subject: [PATCH] Detect and handle chunk header size truncation (#8452)
|
||||
|
||||
This detects if a chunk header size is too large and, if so, closes the
|
||||
connection.
|
||||
---
|
||||
include/tscore/ink_memory.h | 19 +++
|
||||
proxy/http/HttpTunnel.cc | 11 +-
|
||||
src/tscore/Makefile.am | 1 +
|
||||
src/tscore/unit_tests/test_ink_memory.cc | 141 ++++++++++++++++++
|
||||
.../bad_chunked_encoding.test.py | 86 ++++++++++-
|
||||
.../malformed_chunked_header.replay.yaml | 109 ++++++++++++++
|
||||
6 files changed, 364 insertions(+), 3 deletions(-)
|
||||
create mode 100644 src/tscore/unit_tests/test_ink_memory.cc
|
||||
create mode 100644 tests/gold_tests/chunked_encoding/replays/malformed_chunked_header.replay.yaml
|
||||
|
||||
diff --git a/include/tscore/ink_memory.h b/include/tscore/ink_memory.h
|
||||
index fdaaa27c21b..7fd8de1f347 100644
|
||||
--- a/include/tscore/ink_memory.h
|
||||
+++ b/include/tscore/ink_memory.h
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <cstring>
|
||||
#include <strings.h>
|
||||
#include <cinttypes>
|
||||
+#include <limits>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
@@ -205,6 +206,24 @@ ink_zero(T &t)
|
||||
memset(static_cast<void *>(&t), 0, sizeof(t));
|
||||
}
|
||||
|
||||
+/** Verify that we can safely shift value num_places places left.
|
||||
+ *
|
||||
+ * This checks that the shift will not cause the variable to overflow and that
|
||||
+ * the value will not become negative.
|
||||
+ *
|
||||
+ * @param[in] value The value against which to check whether the shift is safe.
|
||||
+ *
|
||||
+ * @param[in] num_places The number of places to check that shifting left is safe.
|
||||
+ *
|
||||
+ */
|
||||
+template <typename T>
|
||||
+inline constexpr bool
|
||||
+can_safely_shift_left(T value, int num_places)
|
||||
+{
|
||||
+ constexpr auto max_value = std::numeric_limits<T>::max();
|
||||
+ return value >= 0 && value <= (max_value >> num_places);
|
||||
+}
|
||||
+
|
||||
/** Scoped resources.
|
||||
|
||||
An instance of this class is used to hold a contingent resource. When this object goes out of scope
|
||||
diff --git a/proxy/http/HttpTunnel.cc b/proxy/http/HttpTunnel.cc
|
||||
index 08837c6290e..564adc23bf6 100644
|
||||
--- a/proxy/http/HttpTunnel.cc
|
||||
+++ b/proxy/http/HttpTunnel.cc
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "HttpSM.h"
|
||||
#include "HttpDebugNames.h"
|
||||
#include "tscore/ParseRules.h"
|
||||
+#include "tscore/ink_memory.h"
|
||||
|
||||
static const int min_block_transfer_bytes = 256;
|
||||
static const char *const CHUNK_HEADER_FMT = "%" PRIx64 "\r\n";
|
||||
@@ -134,8 +135,16 @@ ChunkedHandler::read_size()
|
||||
if (state == CHUNK_READ_SIZE) {
|
||||
// The http spec says the chunked size is always in hex
|
||||
if (ParseRules::is_hex(*tmp)) {
|
||||
+ // Make sure we will not overflow running_sum with our shift.
|
||||
+ if (!can_safely_shift_left(running_sum, 4)) {
|
||||
+ // We have no more space in our variable for the shift.
|
||||
+ state = CHUNK_READ_ERROR;
|
||||
+ done = true;
|
||||
+ break;
|
||||
+ }
|
||||
num_digits++;
|
||||
- running_sum *= 16;
|
||||
+ // Shift over one hex value.
|
||||
+ running_sum <<= 4;
|
||||
|
||||
if (ParseRules::is_digit(*tmp)) {
|
||||
running_sum += *tmp - '0';
|
||||
diff --git a/src/tscore/Makefile.am b/src/tscore/Makefile.am
|
||||
index 43750b2a739..c0ca76c670e 100644
|
||||
--- a/src/tscore/Makefile.am
|
||||
+++ b/src/tscore/Makefile.am
|
||||
@@ -174,6 +174,7 @@ test_tscore_SOURCES = \
|
||||
unit_tests/test_Extendible.cc \
|
||||
unit_tests/test_History.cc \
|
||||
unit_tests/test_ink_inet.cc \
|
||||
+ unit_tests/test_ink_memory.cc \
|
||||
unit_tests/test_IntrusiveHashMap.cc \
|
||||
unit_tests/test_IntrusivePtr.cc \
|
||||
unit_tests/test_IpMap.cc \
|
||||
diff --git a/src/tscore/unit_tests/test_ink_memory.cc b/src/tscore/unit_tests/test_ink_memory.cc
|
||||
new file mode 100644
|
||||
index 00000000000..fa6725b84ca
|
||||
--- /dev/null
|
||||
+++ b/src/tscore/unit_tests/test_ink_memory.cc
|
||||
@@ -0,0 +1,141 @@
|
||||
+/** @file
|
||||
+
|
||||
+ ink_memory unit tests.
|
||||
+
|
||||
+ @section license License
|
||||
+
|
||||
+ Licensed to the Apache Software Foundation (ASF) under one
|
||||
+ or more contributor license agreements. See the NOTICE file
|
||||
+ distributed with this work for additional information
|
||||
+ regarding copyright ownership. The ASF licenses this file
|
||||
+ to you under the Apache License, Version 2.0 (the
|
||||
+ "License"); you may not use this file except in compliance
|
||||
+ with the License. You may obtain a copy of the License at
|
||||
+
|
||||
+ http://www.apache.org/licenses/LICENSE-2.0
|
||||
+
|
||||
+ Unless required by applicable law or agreed to in writing, software
|
||||
+ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
+ See the License for the specific language governing permissions and
|
||||
+ limitations under the License.
|
||||
+*/
|
||||
+
|
||||
+#include <catch.hpp>
|
||||
+#include <cstdint>
|
||||
+#include "tscore/ink_memory.h"
|
||||
+
|
||||
+constexpr void
|
||||
+test_can_safely_shift_int8_t()
|
||||
+{
|
||||
+ constexpr int8_t a = 0;
|
||||
+ static_assert(can_safely_shift_left(a, 0) == true, "shifting 0 is safe");
|
||||
+ static_assert(can_safely_shift_left(a, 4) == true, "shifting 0 is safe");
|
||||
+ static_assert(can_safely_shift_left(a, 8) == true, "shifting 0 is safe");
|
||||
+
|
||||
+ constexpr int8_t b = 1;
|
||||
+ static_assert(can_safely_shift_left(b, 0) == true, "shifting int8_t 1 0 places is safe");
|
||||
+ static_assert(can_safely_shift_left(b, 1) == true, "shifting int8_t 1 1 places is safe");
|
||||
+ static_assert(can_safely_shift_left(b, 6) == true, "shifting int8_t 1 6 places is safe");
|
||||
+ static_assert(can_safely_shift_left(b, 7) == false, "shifting int8_t 1 7 places becomes negative");
|
||||
+ static_assert(can_safely_shift_left(b, 8) == false, "shifting int8_t 1 8 places overflows");
|
||||
+
|
||||
+ constexpr int8_t c = 0xff;
|
||||
+ static_assert(can_safely_shift_left(c, 0) == false, "int8_t 0xff is already negative");
|
||||
+ static_assert(can_safely_shift_left(c, 1) == false, "shifting int8_t 0xff 1 place overflows");
|
||||
+}
|
||||
+
|
||||
+constexpr void
|
||||
+test_can_safely_shift_uint8_t()
|
||||
+{
|
||||
+ constexpr uint8_t a = 0;
|
||||
+ static_assert(can_safely_shift_left(a, 0) == true, "shifting 0 is safe");
|
||||
+ static_assert(can_safely_shift_left(a, 4) == true, "shifting 0 is safe");
|
||||
+ static_assert(can_safely_shift_left(a, 8) == true, "shifting 0 is safe");
|
||||
+
|
||||
+ constexpr uint8_t b = 1;
|
||||
+ static_assert(can_safely_shift_left(b, 0) == true, "shifting uint8_t 1 0 places is safe");
|
||||
+ static_assert(can_safely_shift_left(b, 1) == true, "shifting uint8_t 1 1 places is safe");
|
||||
+ static_assert(can_safely_shift_left(b, 6) == true, "shifting uint8_t 1 6 places is safe");
|
||||
+ static_assert(can_safely_shift_left(b, 7) == true, "shifting uint8_t 1 7 is safe");
|
||||
+ static_assert(can_safely_shift_left(b, 8) == false, "shifting uint8_t 1 8 places overflows");
|
||||
+
|
||||
+ constexpr uint8_t c = 0xff;
|
||||
+ static_assert(can_safely_shift_left(c, 0) == true, "shifting int8_t 0xff 0 places is safe");
|
||||
+ static_assert(can_safely_shift_left(c, 1) == false, "shifting int8_t 0xff 1 place overflows");
|
||||
+}
|
||||
+
|
||||
+constexpr void
|
||||
+test_can_safely_shift_int32_t()
|
||||
+{
|
||||
+ constexpr int32_t a = 0;
|
||||
+ static_assert(can_safely_shift_left(a, 4) == true, "shifting 0 is safe");
|
||||
+
|
||||
+ constexpr int32_t b = 1;
|
||||
+ static_assert(can_safely_shift_left(b, 4) == true, "shifting 1 is safe");
|
||||
+
|
||||
+ constexpr int32_t c = 0x00ff'ffff;
|
||||
+ static_assert(can_safely_shift_left(c, 4) == true, "shifting 0x00ff'ffff is safe");
|
||||
+
|
||||
+ constexpr int32_t d = 0x07ff'ffff;
|
||||
+ static_assert(can_safely_shift_left(d, 4) == true, "shifting 0x07ff'ffff is safe");
|
||||
+
|
||||
+ constexpr int32_t e = -1;
|
||||
+ static_assert(can_safely_shift_left(e, 4) == false, "shifting -1 will result in truncation");
|
||||
+
|
||||
+ constexpr int32_t f = 0x0800'0000;
|
||||
+ static_assert(can_safely_shift_left(f, 4) == false, "shifting 0x0801'0000 will become negative");
|
||||
+
|
||||
+ constexpr int32_t g = 0x0fff'ffff;
|
||||
+ static_assert(can_safely_shift_left(g, 4) == false, "shifting 0x0fff'ffff will become negative");
|
||||
+
|
||||
+ constexpr int32_t h = 0x1000'0000;
|
||||
+ static_assert(can_safely_shift_left(h, 4) == false, "shifting 0x1000'0000 will overflow");
|
||||
+
|
||||
+ constexpr int32_t i = 0xf000'0000;
|
||||
+ static_assert(can_safely_shift_left(i, 4) == false, "shifting 0xf000'0000 will overflow");
|
||||
+
|
||||
+ constexpr int32_t j = 0xf800'0000;
|
||||
+ static_assert(can_safely_shift_left(j, 4) == false, "shifting 0xf800'0000 will become negative");
|
||||
+}
|
||||
+
|
||||
+constexpr void
|
||||
+test_can_safely_shift_uint32_t()
|
||||
+{
|
||||
+ constexpr uint32_t a = 0;
|
||||
+ static_assert(can_safely_shift_left(a, 4) == true, "shifting 0 is safe");
|
||||
+
|
||||
+ constexpr uint32_t b = 1;
|
||||
+ static_assert(can_safely_shift_left(b, 4) == true, "shifting 1 is safe");
|
||||
+
|
||||
+ constexpr uint32_t c = 0x00ff'ffff;
|
||||
+ static_assert(can_safely_shift_left(c, 4) == true, "shifting 0x00ff'ffff is safe");
|
||||
+
|
||||
+ constexpr uint32_t d = 0x07ff'ffff;
|
||||
+ static_assert(can_safely_shift_left(d, 4) == true, "shifting 0x07ff'ffff is safe");
|
||||
+
|
||||
+ constexpr uint32_t e = 0x0800'0000;
|
||||
+ static_assert(can_safely_shift_left(e, 4) == true, "shifting unisgned 0x0800'0000 is safe");
|
||||
+
|
||||
+ constexpr uint32_t f = 0x0fff'ffff;
|
||||
+ static_assert(can_safely_shift_left(f, 4) == true, "shifting unsigned 0x0fff'ffff is safe");
|
||||
+
|
||||
+ constexpr uint32_t g = 0x1000'0000;
|
||||
+ static_assert(can_safely_shift_left(g, 4) == false, "shifting 0x1000'0000 will overflow");
|
||||
+
|
||||
+ constexpr uint32_t h = 0xf000'0000;
|
||||
+ static_assert(can_safely_shift_left(h, 4) == false, "shifting 0xf000'0000 will overflow");
|
||||
+
|
||||
+ constexpr uint32_t i = 0xf800'0000;
|
||||
+ static_assert(can_safely_shift_left(i, 4) == false, "shifting 0xf800'0000 will become negative");
|
||||
+}
|
||||
+
|
||||
+TEST_CASE("can_safely_shift", "[libts][ink_inet][memory]")
|
||||
+{
|
||||
+ // can_safely_shift_left is a constexpr function, therefore all these checks are
|
||||
+ // done at compile time and REQUIRES calls are not necessary.
|
||||
+ test_can_safely_shift_int8_t();
|
||||
+ test_can_safely_shift_uint8_t();
|
||||
+ test_can_safely_shift_int32_t();
|
||||
+ test_can_safely_shift_uint32_t();
|
||||
+}
|
||||
diff --git a/tests/gold_tests/chunked_encoding/bad_chunked_encoding.test.py b/tests/gold_tests/chunked_encoding/bad_chunked_encoding.test.py
|
||||
index cdfc0bf9cd2..38e4206687b 100644
|
||||
--- a/tests/gold_tests/chunked_encoding/bad_chunked_encoding.test.py
|
||||
+++ b/tests/gold_tests/chunked_encoding/bad_chunked_encoding.test.py
|
||||
@@ -25,7 +25,7 @@
|
||||
Test.ContinueOnFail = True
|
||||
|
||||
# Define default ATS
|
||||
-ts = Test.MakeATSProcess("ts", select_ports=True, enable_tls=False)
|
||||
+ts = Test.MakeATSProcess("ts1", select_ports=True, enable_tls=False)
|
||||
server = Test.MakeOriginServer("server")
|
||||
|
||||
testName = ""
|
||||
@@ -53,7 +53,7 @@
|
||||
ts.Variables.port)
|
||||
tr.Processes.Default.ReturnCode = 0
|
||||
tr.Processes.Default.StartBefore(server)
|
||||
-tr.Processes.Default.StartBefore(Test.Processes.ts)
|
||||
+tr.Processes.Default.StartBefore(ts)
|
||||
tr.Processes.Default.Streams.All = Testers.ContainsExpression("501 Field not implemented", "Should fail")
|
||||
tr.Processes.Default.Streams.All = Testers.ExcludesExpression("200 OK", "Should not succeed")
|
||||
tr.StillRunningAfter = server
|
||||
@@ -69,3 +69,85 @@
|
||||
tr.Processes.Default.Streams.All = Testers.ExcludesExpression("200 OK", "Should not succeed")
|
||||
tr.StillRunningAfter = server
|
||||
tr.StillRunningAfter = ts
|
||||
+
|
||||
+
|
||||
+class MalformedChunkHeaderTest:
|
||||
+ chunkedReplayFile = "replays/malformed_chunked_header.replay.yaml"
|
||||
+
|
||||
+ def __init__(self):
|
||||
+ self.setupOriginServer()
|
||||
+ self.setupTS()
|
||||
+
|
||||
+ def setupOriginServer(self):
|
||||
+ self.server = Test.MakeVerifierServerProcess("verifier-server", self.chunkedReplayFile)
|
||||
+
|
||||
+ # The server's responses will fail the first two transactions
|
||||
+ # because ATS will close the connection due to the malformed
|
||||
+ # chunk headers.
|
||||
+ self.server.Streams.stdout += Testers.ContainsExpression(
|
||||
+ "Header write for key 1 failed",
|
||||
+ "Verify that writing the first response failed.")
|
||||
+ self.server.Streams.stdout += Testers.ContainsExpression(
|
||||
+ "Header write for key 2 failed",
|
||||
+ "Verify that writing the second response failed.")
|
||||
+
|
||||
+ # ATS should close the connection before any body gets through.
|
||||
+ # "abc" is the body sent for each of these chunked cases.
|
||||
+ self.server.Streams.stdout += Testers.ExcludesExpression(
|
||||
+ "abc",
|
||||
+ "Verify that the body never got through.")
|
||||
+
|
||||
+ def setupTS(self):
|
||||
+ self.ts = Test.MakeATSProcess("ts2", enable_tls=True, enable_cache=False)
|
||||
+ self.ts.addDefaultSSLFiles()
|
||||
+ self.ts.Disk.records_config.update({
|
||||
+ "proxy.config.diags.debug.enabled": 1,
|
||||
+ "proxy.config.diags.debug.tags": "http",
|
||||
+ "proxy.config.ssl.server.cert.path": f'{self.ts.Variables.SSLDir}',
|
||||
+ "proxy.config.ssl.server.private_key.path": f'{self.ts.Variables.SSLDir}',
|
||||
+ "proxy.config.ssl.client.verify.server.policy": 'PERMISSIVE',
|
||||
+ })
|
||||
+ self.ts.Disk.ssl_multicert_config.AddLine(
|
||||
+ 'dest_ip=* ssl_cert_name=server.pem ssl_key_name=server.key'
|
||||
+ )
|
||||
+ self.ts.Disk.remap_config.AddLine(
|
||||
+ f"map / http://127.0.0.1:{self.server.Variables.http_port}/",
|
||||
+ )
|
||||
+ self.ts.Streams.stderr += Testers.ContainsExpression(
|
||||
+ "user agent post chunk decoding error",
|
||||
+ "Verify that ATS detected a problem parsing a chunk.")
|
||||
+
|
||||
+ def runChunkedTraffic(self):
|
||||
+ tr = Test.AddTestRun()
|
||||
+ tr.AddVerifierClientProcess(
|
||||
+ "client",
|
||||
+ self.chunkedReplayFile,
|
||||
+ http_ports=[self.ts.Variables.port],
|
||||
+ https_ports=[self.ts.Variables.ssl_port],
|
||||
+ other_args='--thread-limit 1')
|
||||
+ tr.Processes.Default.StartBefore(self.server)
|
||||
+ tr.Processes.Default.StartBefore(self.ts)
|
||||
+ tr.StillRunningAfter = self.server
|
||||
+ tr.StillRunningAfter = self.ts
|
||||
+
|
||||
+ # The aborted connections will result in errors and a non-zero return
|
||||
+ # code from the verifier client.
|
||||
+ tr.Processes.Default.ReturnCode = 1
|
||||
+ tr.Processes.Default.Streams.stdout += Testers.ContainsExpression(
|
||||
+ "Failed HTTP/1 transaction with key=3",
|
||||
+ "Verify that ATS closed the third transaction.")
|
||||
+ tr.Processes.Default.Streams.stdout += Testers.ContainsExpression(
|
||||
+ "Failed HTTP/1 transaction with key=4",
|
||||
+ "Verify that ATS closed the fourth transaction.")
|
||||
+
|
||||
+ # ATS should close the connection before any body gets through.
|
||||
+ # "abc" is the body sent for each of these chunked cases.
|
||||
+ tr.Processes.Default.Streams.stdout += Testers.ExcludesExpression(
|
||||
+ "abc",
|
||||
+ "Verify that the body never got through.")
|
||||
+
|
||||
+ def run(self):
|
||||
+ self.runChunkedTraffic()
|
||||
+
|
||||
+
|
||||
+MalformedChunkHeaderTest().run()
|
||||
diff --git a/tests/gold_tests/chunked_encoding/replays/malformed_chunked_header.replay.yaml b/tests/gold_tests/chunked_encoding/replays/malformed_chunked_header.replay.yaml
|
||||
new file mode 100644
|
||||
index 00000000000..c6091ab4ee1
|
||||
--- /dev/null
|
||||
+++ b/tests/gold_tests/chunked_encoding/replays/malformed_chunked_header.replay.yaml
|
||||
@@ -0,0 +1,109 @@
|
||||
+# Licensed to the Apache Software Foundation (ASF) under one
|
||||
+# or more contributor license agreements. See the NOTICE file
|
||||
+# distributed with this work for additional information
|
||||
+# regarding copyright ownership. The ASF licenses this file
|
||||
+# to you under the Apache License, Version 2.0 (the
|
||||
+# "License"); you may not use this file except in compliance
|
||||
+# with the License. You may obtain a copy of the License at
|
||||
+#
|
||||
+# http://www.apache.org/licenses/LICENSE-2.0
|
||||
+#
|
||||
+# Unless required by applicable law or agreed to in writing, software
|
||||
+# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
+# See the License for the specific language governing permissions and
|
||||
+# limitations under the License.
|
||||
+
|
||||
+meta:
|
||||
+ version: "1.0"
|
||||
+
|
||||
+sessions:
|
||||
+- transactions:
|
||||
+ - client-request:
|
||||
+ method: "POST"
|
||||
+ version: "1.1"
|
||||
+ url: /malformed/chunk/header
|
||||
+ headers:
|
||||
+ fields:
|
||||
+ - [ Host, example.com ]
|
||||
+ - [ Transfer-Encoding, chunked ]
|
||||
+ - [ uuid, 1 ]
|
||||
+ content:
|
||||
+ transfer: plain
|
||||
+ encoding: uri
|
||||
+ # Chunk header sizes are in hex, so a size of `z` is malformed.
|
||||
+ data: z%0D%0Aabc%0D%0A0%0D%0A%0D%0A
|
||||
+
|
||||
+ # The connection will be dropped and this response will not go out.
|
||||
+ server-response:
|
||||
+ status: 200
|
||||
+
|
||||
+- transactions:
|
||||
+ - client-request:
|
||||
+ method: "POST"
|
||||
+ version: "1.1"
|
||||
+ url: /large/chunk/size/header
|
||||
+ headers:
|
||||
+ fields:
|
||||
+ - [ Host, example.com ]
|
||||
+ - [ Transfer-Encoding, chunked ]
|
||||
+ - [ uuid, 2 ]
|
||||
+ content:
|
||||
+ transfer: plain
|
||||
+ encoding: uri
|
||||
+ # Super large chunk header, larger than will fit in an int.
|
||||
+ data: 111111113%0D%0Aabc%0D%0A0%0D%0A%0D%0A
|
||||
+
|
||||
+ # The connection will be dropped and this response will not go out.
|
||||
+ server-response:
|
||||
+ status: 200
|
||||
+
|
||||
+ #
|
||||
+ # Now repeat the above two malformed chunk header tests, but on the server
|
||||
+ # side.
|
||||
+ #
|
||||
+- transactions:
|
||||
+ - client-request:
|
||||
+ method: "GET"
|
||||
+ version: "1.1"
|
||||
+ url: /response/malformed/chunk/size
|
||||
+ headers:
|
||||
+ fields:
|
||||
+ - [ Host, example.com ]
|
||||
+ - [ uuid, 3 ]
|
||||
+
|
||||
+ # The connection will be dropped and this response will not go out.
|
||||
+ server-response:
|
||||
+ status: 200
|
||||
+ reason: OK
|
||||
+ headers:
|
||||
+ fields:
|
||||
+ - [ Transfer-Encoding, chunked ]
|
||||
+ content:
|
||||
+ transfer: plain
|
||||
+ encoding: uri
|
||||
+ # Chunk header sizes are in hex, so a size of `z` is malformed.
|
||||
+ data: z%0D%0Aabc%0D%0A0%0D%0A%0D%0A
|
||||
+
|
||||
+- transactions:
|
||||
+ - client-request:
|
||||
+ method: "GET"
|
||||
+ version: "1.1"
|
||||
+ url: /response/large/chunk/size
|
||||
+ headers:
|
||||
+ fields:
|
||||
+ - [ Host, example.com ]
|
||||
+ - [ uuid, 4 ]
|
||||
+
|
||||
+ # The connection will be dropped and this response will not go out.
|
||||
+ server-response:
|
||||
+ status: 200
|
||||
+ reason: OK
|
||||
+ headers:
|
||||
+ fields:
|
||||
+ - [ Transfer-Encoding, chunked ]
|
||||
+ content:
|
||||
+ transfer: plain
|
||||
+ encoding: uri
|
||||
+ # Super large chunk header, larger than will fit in an int.
|
||||
+ data: 111111113%0D%0Aabc%0D%0A0%0D%0A%0D%0A
|
||||
@ -1,77 +0,0 @@
|
||||
From 268b540edae0b3e51d033795a4dd7404a5756a93 Mon Sep 17 00:00:00 2001
|
||||
From: Masaori Koshiba <masaori@apache.org>
|
||||
Date: Thu, 28 Oct 2021 01:53:14 +0900
|
||||
Subject: [PATCH] Ignore ECONNABORTED on blocking accept (#8453)
|
||||
|
||||
---
|
||||
iocore/net/P_UnixNet.h | 4 +++-
|
||||
iocore/net/UnixNetAccept.cc | 30 ++++++++++++++++++++----------
|
||||
2 files changed, 23 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/iocore/net/P_UnixNet.h b/iocore/net/P_UnixNet.h
|
||||
index 0043e1d763c..cff9439e9a4 100644
|
||||
--- a/iocore/net/P_UnixNet.h
|
||||
+++ b/iocore/net/P_UnixNet.h
|
||||
@@ -480,6 +480,7 @@ change_net_connections_throttle(const char *token, RecDataT data_type, RecData v
|
||||
return 0;
|
||||
}
|
||||
|
||||
+// 2 - ignore
|
||||
// 1 - transient
|
||||
// 0 - report as warning
|
||||
// -1 - fatal
|
||||
@@ -487,8 +488,9 @@ TS_INLINE int
|
||||
accept_error_seriousness(int res)
|
||||
{
|
||||
switch (res) {
|
||||
- case -EAGAIN:
|
||||
case -ECONNABORTED:
|
||||
+ return 2;
|
||||
+ case -EAGAIN:
|
||||
case -ECONNRESET: // for Linux
|
||||
case -EPIPE: // also for Linux
|
||||
return 1;
|
||||
diff --git a/iocore/net/UnixNetAccept.cc b/iocore/net/UnixNetAccept.cc
|
||||
index d1ecc22d185..1ce5923b8ff 100644
|
||||
--- a/iocore/net/UnixNetAccept.cc
|
||||
+++ b/iocore/net/UnixNetAccept.cc
|
||||
@@ -295,19 +295,29 @@ NetAccept::do_blocking_accept(EThread *t)
|
||||
do {
|
||||
if ((res = server.accept(&con)) < 0) {
|
||||
int seriousness = accept_error_seriousness(res);
|
||||
- if (seriousness >= 0) { // not so bad
|
||||
- if (!seriousness) { // bad enough to warn about
|
||||
- check_transient_accept_error(res);
|
||||
- }
|
||||
+ switch (seriousness) {
|
||||
+ case 0:
|
||||
+ // bad enough to warn about
|
||||
+ check_transient_accept_error(res);
|
||||
safe_delay(net_throttle_delay);
|
||||
return 0;
|
||||
+ case 1:
|
||||
+ // not so bad but needs delay
|
||||
+ safe_delay(net_throttle_delay);
|
||||
+ return 0;
|
||||
+ case 2:
|
||||
+ // ignore
|
||||
+ return 0;
|
||||
+ case -1:
|
||||
+ [[fallthrough]];
|
||||
+ default:
|
||||
+ if (!action_->cancelled) {
|
||||
+ SCOPED_MUTEX_LOCK(lock, action_->mutex ? action_->mutex : t->mutex, t);
|
||||
+ action_->continuation->handleEvent(EVENT_ERROR, (void *)static_cast<intptr_t>(res));
|
||||
+ Warning("accept thread received fatal error: errno = %d", errno);
|
||||
+ }
|
||||
+ return -1;
|
||||
}
|
||||
- if (!action_->cancelled) {
|
||||
- SCOPED_MUTEX_LOCK(lock, action_->mutex ? action_->mutex : t->mutex, t);
|
||||
- action_->continuation->handleEvent(EVENT_ERROR, (void *)static_cast<intptr_t>(res));
|
||||
- Warning("accept thread received fatal error: errno = %d", errno);
|
||||
- }
|
||||
- return -1;
|
||||
}
|
||||
// check for throttle
|
||||
if (!opt.backdoor && check_net_throttle(ACCEPT)) {
|
||||
@ -1,43 +0,0 @@
|
||||
From 02b17dbe3cff71ffd31577d872e077531124d207 Mon Sep 17 00:00:00 2001
|
||||
From: Masaori Koshiba <masaori@apache.org>
|
||||
Date: Fri, 29 Oct 2021 09:34:12 +0900
|
||||
Subject: [PATCH] Check length before search accept-encoding header (#8475)
|
||||
|
||||
---
|
||||
plugins/stats_over_http/stats_over_http.c | 10 +++++++---
|
||||
1 file changed, 7 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/plugins/stats_over_http/stats_over_http.c b/plugins/stats_over_http/stats_over_http.c
|
||||
index b78575d5cf5..bb75fe791b5 100644
|
||||
--- a/plugins/stats_over_http/stats_over_http.c
|
||||
+++ b/plugins/stats_over_http/stats_over_http.c
|
||||
@@ -61,6 +61,10 @@
|
||||
/* global holding the path used for access to this JSON data */
|
||||
#define DEFAULT_URL_PATH "_stats"
|
||||
|
||||
+// TODO: replace with TS_HTTP_* when BROTLI is supported
|
||||
+#define HTTP_VALUE_BR "BR"
|
||||
+#define HTTP_LEN_BR 2
|
||||
+
|
||||
// from mod_deflate:
|
||||
// ZLIB's compression algorithm uses a
|
||||
// 0-9 based scale that GZIP does where '1' is 'Best speed'
|
||||
@@ -618,15 +622,15 @@ stats_origin(TSCont contp ATS_UNUSED, TSEvent event ATS_UNUSED, void *edata)
|
||||
if (accept_encoding_field != TS_NULL_MLOC) {
|
||||
int len = -1;
|
||||
const char *str = TSMimeHdrFieldValueStringGet(reqp, hdr_loc, accept_encoding_field, -1, &len);
|
||||
- if (strstr(str, "deflate") != NULL) {
|
||||
+ if (len >= TS_HTTP_LEN_DEFLATE && strstr(str, TS_HTTP_VALUE_DEFLATE) != NULL) {
|
||||
TSDebug(PLUGIN_NAME, "Saw deflate in accept encoding");
|
||||
my_state->encoding = init_gzip(my_state, DEFLATE_MODE);
|
||||
- } else if (strstr(str, "gzip") != NULL) {
|
||||
+ } else if (len >= TS_HTTP_LEN_GZIP && strstr(str, TS_HTTP_VALUE_GZIP) != NULL) {
|
||||
TSDebug(PLUGIN_NAME, "Saw gzip in accept encoding");
|
||||
my_state->encoding = init_gzip(my_state, GZIP_MODE);
|
||||
}
|
||||
#if HAVE_BROTLI_ENCODE_H
|
||||
- else if (strstr(str, "br") != NULL) {
|
||||
+ else if (len >= HTTP_LEN_BR && strstr(str, HTTP_VALUE_BR) != NULL) {
|
||||
TSDebug(PLUGIN_NAME, "Saw br in accept encoding");
|
||||
my_state->encoding = init_br(my_state);
|
||||
}
|
||||
@ -1,35 +0,0 @@
|
||||
From 7a93f208f32889ca5eb285dda87a4912fa30886a Mon Sep 17 00:00:00 2001
|
||||
From: Jean-Baptiste Favre <jean-baptiste.favre@blablacar.com>
|
||||
Date: Tue, 19 Oct 2021 08:42:04 +0200
|
||||
Subject: [PATCH] Fix traffic_top build when using -Werror=format-security
|
||||
Reference: https://github.com/apache/trafficserver/pull/8437
|
||||
|
||||
---
|
||||
src/traffic_top/traffic_top.cc | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/traffic_top/traffic_top.cc b/src/traffic_top/traffic_top.cc
|
||||
index d33d682..2ac6b2a 100644
|
||||
--- a/src/traffic_top/traffic_top.cc
|
||||
+++ b/src/traffic_top/traffic_top.cc
|
||||
@@ -126,7 +126,7 @@ prettyPrint(const int x, const int y, const double number, const int type)
|
||||
}
|
||||
attron(COLOR_PAIR(color));
|
||||
attron(A_BOLD);
|
||||
- mvprintw(y, x, buffer);
|
||||
+ mvprintw(y, x, "%s", buffer);
|
||||
attroff(COLOR_PAIR(color));
|
||||
attroff(A_BOLD);
|
||||
}
|
||||
@@ -143,7 +143,7 @@ makeTable(const int x, const int y, const list<string> &items, Stats &stats)
|
||||
int type;
|
||||
|
||||
stats.getStat(item, value, prettyName, type);
|
||||
- mvprintw(my_y, x, prettyName.c_str());
|
||||
+ mvprintw(my_y, x, "%s", prettyName.c_str());
|
||||
prettyPrint(x + 10, my_y++, value, type);
|
||||
}
|
||||
}
|
||||
--
|
||||
2.27.0
|
||||
|
||||
Binary file not shown.
@ -1,20 +1,14 @@
|
||||
%define _hardened_build 1
|
||||
%{!?release: %define release 2}
|
||||
Name: trafficserver
|
||||
Version: 9.1.0
|
||||
Release: 5
|
||||
Version: 9.1.2
|
||||
Release: 1
|
||||
Summary: Apache Traffic Server, a reverse, forward and transparent HTTP proxy cache
|
||||
License: Apache-2.0
|
||||
URL: https://trafficserver.apache.org/
|
||||
Source0: http://www.apache.org/dist/%{name}/%{name}-%{version}.tar.bz2
|
||||
Patch0000: Add-openeuler-support.patch
|
||||
Patch0001: CVE-2021-37147.patch
|
||||
Patch0002: CVE-2021-37149.patch
|
||||
Patch0003: CVE-2021-41585.patch
|
||||
Patch0004: CVE-2021-43082.patch
|
||||
Patch0005: Fix-status-failure-after-stopping-service.patch
|
||||
Patch0006: Fix-log-in-debug-mode.patch
|
||||
Patch0007: Fix-traffic_top-build-when-using-Werror-format-security.patch
|
||||
Patch0001: Fix-status-failure-after-stopping-service.patch
|
||||
Patch0002: Fix-log-in-debug-mode.patch
|
||||
BuildRequires: expat-devel hwloc-devel openssl-devel pcre-devel zlib-devel xz-devel
|
||||
BuildRequires: libcurl-devel ncurses-devel gcc gcc-c++ perl-ExtUtils-MakeMaker
|
||||
BuildRequires: libcap-devel cmake libunwind-devel automake
|
||||
@ -119,6 +113,9 @@ getent passwd ats >/dev/null || useradd -r -u 176 -g ats -d / -s /sbin/nologin -
|
||||
%{_datadir}/pkgconfig/trafficserver.pc
|
||||
|
||||
%changelog
|
||||
* Thu May 19 2022 wangkai <wangkai385@h-partners.com> - 9.1.2-1
|
||||
- Update to 9.1.2 fox fix CVE-2021-44040
|
||||
|
||||
* Mon May 09 2022 wulei <wulei80@h-partners.com> - 9.1.0-5
|
||||
- Fix traffic_top build when using -Werror=format-security
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user