From 37bca06f1fe319237067c6972fe7d6b93fd7ba5c Mon Sep 17 00:00:00 2001 From: phlax Date: Tue, 13 Feb 2024 14:06:19 +0000 Subject: [PATCH 01/19] repo: Dev 1.27.4 (#32330) Signed-off-by: Ryan Northey --- VERSION.txt | 2 +- changelogs/current.yaml | 61 +++++++++-------------------------------- 2 files changed, 14 insertions(+), 49 deletions(-) diff --git a/VERSION.txt b/VERSION.txt index 3bae5204be9e..30eedfa5bbb6 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -1.27.3 +1.27.4-dev diff --git a/changelogs/current.yaml b/changelogs/current.yaml index a67d0b6cabb2..9ecf0d6e48ce 100644 --- a/changelogs/current.yaml +++ b/changelogs/current.yaml @@ -1,52 +1,17 @@ -date: February 9, 2024 +date: Pending + +behavior_changes: +# *Changes that are expected to cause an incompatibility if applicable; deployment changes are likely required* minor_behavior_changes: -- area: access_log - change: | - When emitting grpc logs, only downstream filter state was used. Now, both downstream and upstream filter states will be tried - to find the keys configured in filter_state_objects_to_log. +# *Changes that may cause incompatibilities for some users, but should not for most* bug_fixes: -- area: buffer - change: | - Fixed a bug (https://github.com/envoyproxy/envoy/issues/28760) that the internal listener causes an undefined - behavior due to the unintended release of the buffer memory. -- area: http - change: | - Fixed recursion when HTTP connection is disconnected due to a high number of premature resets. -- area: grpc - change: | - Fixed a bug in gRPC async client cache which intermittently causes CPU spikes due to busy loop in timer expiration. -- area: tracing - change: | - Fixed a bug where Datadog spans tagged as errors would not have the appropriate error property set. -- area: tracing - change: | - Fixed a bug where child spans produced by the Datadog tracer would have an incorrect operation name. -- area: tracing - change: | - Fixed a bug that caused the Datadog tracing extension to drop traces that - should be kept on account of an extracted sampling decision. -- area: proxy protocol - change: | - fixed a crash when Envoy is configured for PROXY protocol on both a listener and cluster, and the listener receives - a PROXY protocol header with address type LOCAL (typically used for health checks). -- area: proxy_protocol - change: | - Fix crash due to uncaught exception when the operating system does not support an address type (such as IPv6) that is - received in a proxy protocol header. Connections will instead be dropped/reset. -- area: proxy_protocol - change: | - Fixed a bug where TLVs with non utf8 characters were inserted as protobuf values into filter metadata circumventing - ext_authz checks when ``failure_mode_allow`` is set to ``true``. -- area: tls - change: | - Fix crash due to uncaught exception when the operating system does not support an address type (such as IPv6) that is - received in an mTLS client cert IP SAN. These SANs will be ignored. This applies only when using formatter - ``%DOWNSTREAM_PEER_IP_SAN%``. -- area: http - change: | - Fixed crash when HTTP request idle and per try timeouts occurs within backoff interval. -- area: url matching - change: | - Fixed excessive CPU utilization when using regex URL template matcher. +# *Changes expected to improve the state of the world and are unlikely to have negative effects* + +removed_config_or_runtime: +# *Normally occurs at the end of the* :ref:`deprecation period ` + +new_features: + +deprecated: From cdc5852f6e5c54ad2ab4c1a8ada744d85296cfb7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Feb 2024 07:01:59 +0000 Subject: [PATCH 02/19] build(deps): bump distroless/base-nossl-debian12 from `51ab103` to `49edf70` in /ci (#32348) build(deps): bump distroless/base-nossl-debian12 in /ci Bumps distroless/base-nossl-debian12 from `51ab103` to `49edf70`. --- updated-dependencies: - dependency-name: distroless/base-nossl-debian12 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: Ryan Northey --- ci/Dockerfile-envoy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/Dockerfile-envoy b/ci/Dockerfile-envoy index 7f6f0bd13911..cf7e0d7dc0b3 100644 --- a/ci/Dockerfile-envoy +++ b/ci/Dockerfile-envoy @@ -58,7 +58,7 @@ COPY --chown=0:0 --chmod=755 \ # STAGE: envoy-distroless -FROM gcr.io/distroless/base-nossl-debian12:nonroot@sha256:51ab103bb161fdf8fee4c6311a2d41f484effc409d4f4c58342ab68b2da7ccc2 AS envoy-distroless +FROM gcr.io/distroless/base-nossl-debian12:nonroot@sha256:49edf7003af1015b0841f34a04197e8b1c5f1d0c91e897c97749c78ee38b8ec2 AS envoy-distroless EXPOSE 10000 ENTRYPOINT ["/usr/local/bin/envoy"] CMD ["-c", "/etc/envoy/envoy.yaml"] From 08639893233945e0f2c82cc3680f8e2cc89fe001 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 27 Feb 2024 13:43:52 +0000 Subject: [PATCH 03/19] build(deps): bump distroless/base-nossl-debian12 from `49edf70` to `0e777c6` in /ci (#32576) build(deps): bump distroless/base-nossl-debian12 in /ci Bumps distroless/base-nossl-debian12 from `49edf70` to `0e777c6`. --- updated-dependencies: - dependency-name: distroless/base-nossl-debian12 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: Ryan Northey --- ci/Dockerfile-envoy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/Dockerfile-envoy b/ci/Dockerfile-envoy index cf7e0d7dc0b3..9e4e156bc75e 100644 --- a/ci/Dockerfile-envoy +++ b/ci/Dockerfile-envoy @@ -58,7 +58,7 @@ COPY --chown=0:0 --chmod=755 \ # STAGE: envoy-distroless -FROM gcr.io/distroless/base-nossl-debian12:nonroot@sha256:49edf7003af1015b0841f34a04197e8b1c5f1d0c91e897c97749c78ee38b8ec2 AS envoy-distroless +FROM gcr.io/distroless/base-nossl-debian12:nonroot@sha256:0e777c69ba810353b9f3f2033280bbe7d029d81fa55760f6eec817ef595aa19c AS envoy-distroless EXPOSE 10000 ENTRYPOINT ["/usr/local/bin/envoy"] CMD ["-c", "/etc/envoy/envoy.yaml"] From 8ca7973b9b1f2f639e1ba87aeeb6aa23c6885769 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 29 Feb 2024 10:26:18 +0000 Subject: [PATCH 04/19] build(deps): bump distroless/base-nossl-debian12 from `0e777c6` to `28dc895` in /ci (#32613) build(deps): bump distroless/base-nossl-debian12 in /ci Bumps distroless/base-nossl-debian12 from `0e777c6` to `28dc895`. --- updated-dependencies: - dependency-name: distroless/base-nossl-debian12 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: Ryan Northey --- ci/Dockerfile-envoy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/Dockerfile-envoy b/ci/Dockerfile-envoy index 9e4e156bc75e..b9a043670d90 100644 --- a/ci/Dockerfile-envoy +++ b/ci/Dockerfile-envoy @@ -58,7 +58,7 @@ COPY --chown=0:0 --chmod=755 \ # STAGE: envoy-distroless -FROM gcr.io/distroless/base-nossl-debian12:nonroot@sha256:0e777c69ba810353b9f3f2033280bbe7d029d81fa55760f6eec817ef595aa19c AS envoy-distroless +FROM gcr.io/distroless/base-nossl-debian12:nonroot@sha256:28dc8956c04a92ffc192d06c5da69fa747c675ee44043ba18128e747c2f539f5 AS envoy-distroless EXPOSE 10000 ENTRYPOINT ["/usr/local/bin/envoy"] CMD ["-c", "/etc/envoy/envoy.yaml"] From 659649e0019a455e2157605271096c231a20b7ea Mon Sep 17 00:00:00 2001 From: phlax Date: Fri, 23 Feb 2024 09:10:36 +0000 Subject: [PATCH 05/19] ci/macos: Use Engflow for bazel cache (#32520) Signed-off-by: Ryan Northey Signed-off-by: phlax --- .bazelrc | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/.bazelrc b/.bazelrc index 7533ffc8a62f..a14ceec398de 100644 --- a/.bazelrc +++ b/.bazelrc @@ -492,16 +492,18 @@ build:rbe-engflow --remote_timeout=3600s build:rbe-engflow --bes_timeout=3600s build:rbe-engflow --bes_upload_mode=fully_async -build:rbe-envoy-engflow --google_default_credentials=false -build:rbe-envoy-engflow --remote_cache=grpcs://morganite.cluster.engflow.com +build:cache-envoy-engflow --google_default_credentials=false +build:cache-envoy-engflow --remote_cache=grpcs://morganite.cluster.engflow.com +build:cache-envoy-engflow --remote_timeout=3600s +build:cache-envoy-engflow --credential_helper=*.engflow.com=%workspace%/bazel/engflow-bazel-credential-helper.sh +build:cache-envoy-engflow --grpc_keepalive_time=30s +build:bes-envoy-engflow --bes_backend=grpcs://morganite.cluster.engflow.com/ +build:bes-envoy-engflow --bes_results_url=https://morganite.cluster.engflow.com/invocation/ +build:bes-envoy-engflow --bes_timeout=3600s +build:bes-envoy-engflow --bes_upload_mode=fully_async +build:rbe-envoy-engflow --config=cache-envoy-engflow +build:rbe-envoy-engflow --config=bes-envoy-engflow build:rbe-envoy-engflow --remote_executor=grpcs://morganite.cluster.engflow.com -build:rbe-envoy-engflow --bes_backend=grpcs://morganite.cluster.engflow.com/ -build:rbe-envoy-engflow --bes_results_url=https://morganite.cluster.engflow.com/invocation/ -build:rbe-envoy-engflow --credential_helper=*.engflow.com=%workspace%/bazel/engflow-bazel-credential-helper.sh -build:rbe-envoy-engflow --grpc_keepalive_time=30s -build:rbe-envoy-engflow --remote_timeout=3600s -build:rbe-envoy-engflow --bes_timeout=3600s -build:rbe-envoy-engflow --bes_upload_mode=fully_async build:rbe-envoy-engflow --remote_default_exec_properties=container-image=docker://docker.io/envoyproxy/envoy-build-ubuntu:fdd65c6270a8507a18d5acd6cf19a18cb695e4fa@sha256:3c8a3ce6f90dcfb5d09dc8f79bb01404d3526d420061f9a176e0a8e91e1e573e ############################################################################# From 3db916fa9a36e749a48f55296ee1826e01a708c5 Mon Sep 17 00:00:00 2001 From: Kuat Date: Fri, 23 Feb 2024 01:11:34 -0800 Subject: [PATCH 06/19] google_grpc: add a runtime flag to disable TLSv1.3 (#32532) * google_grpc: add a runtime flag to disable TLSv1.3 (#32315) Change-Id: Id88723a81d4b1586bf12be6f4dc7a81ae7b0d9c4 Commit Message: Adds a temporary runtime flag to disable TLSv1.3 by gRPC SDK until a proper xDS extension can be added. Additional Description: Risk Level: low, default false Testing: regression Change-Id: I34daae55ede7c8093b0dac1fa6ff5a5dc8df677d Signed-off-by: Kuat Yessenov --- changelogs/current.yaml | 5 +++ source/common/grpc/BUILD | 1 + source/common/grpc/google_grpc_creds_impl.cc | 38 +++++++++++++++---- source/common/runtime/runtime_features.cc | 4 ++ test/common/grpc/BUILD | 1 + .../grpc/grpc_client_integration_test.cc | 24 ++++++++++++ .../grpc_client_integration_test_harness.h | 16 +++++++- 7 files changed, 81 insertions(+), 8 deletions(-) diff --git a/changelogs/current.yaml b/changelogs/current.yaml index 9ecf0d6e48ce..2b8dc99df2e0 100644 --- a/changelogs/current.yaml +++ b/changelogs/current.yaml @@ -13,5 +13,10 @@ removed_config_or_runtime: # *Normally occurs at the end of the* :ref:`deprecation period ` new_features: +- area: google_grpc + change: | + Added an off-by-default runtime flag + ``envoy.reloadable_features.google_grpc_disable_tls_13`` to disable TLSv1.3 + usage by gRPC SDK for ``google_grpc`` services. deprecated: diff --git a/source/common/grpc/BUILD b/source/common/grpc/BUILD index 96d1ed06353d..d662c6863e4b 100644 --- a/source/common/grpc/BUILD +++ b/source/common/grpc/BUILD @@ -210,6 +210,7 @@ envoy_cc_library( "//envoy/grpc:google_grpc_creds_interface", "//envoy/registry", "//source/common/config:datasource_lib", + "//source/common/runtime:runtime_lib", "@envoy_api//envoy/config/core/v3:pkg_cc_proto", ], alwayslink = LEGACY_ALWAYSLINK, diff --git a/source/common/grpc/google_grpc_creds_impl.cc b/source/common/grpc/google_grpc_creds_impl.cc index ae49d3257a7f..5aa2ea91fd8a 100644 --- a/source/common/grpc/google_grpc_creds_impl.cc +++ b/source/common/grpc/google_grpc_creds_impl.cc @@ -4,6 +4,9 @@ #include "envoy/grpc/google_grpc_creds.h" #include "source/common/config/datasource.h" +#include "source/common/runtime/runtime_features.h" + +#include "grpcpp/security/tls_certificate_provider.h" namespace Envoy { namespace Grpc { @@ -15,12 +18,29 @@ std::shared_ptr CredsUtility::getChannelCredentials( case envoy::config::core::v3::GrpcService::GoogleGrpc::ChannelCredentials:: CredentialSpecifierCase::kSslCredentials: { const auto& ssl_credentials = google_grpc.channel_credentials().ssl_credentials(); - const grpc::SslCredentialsOptions ssl_credentials_options = { - Config::DataSource::read(ssl_credentials.root_certs(), true, api), - Config::DataSource::read(ssl_credentials.private_key(), true, api), - Config::DataSource::read(ssl_credentials.cert_chain(), true, api), - }; - return grpc::SslCredentials(ssl_credentials_options); + const auto root_certs = Config::DataSource::read(ssl_credentials.root_certs(), true, api); + const auto private_key = Config::DataSource::read(ssl_credentials.private_key(), true, api); + const auto cert_chain = Config::DataSource::read(ssl_credentials.cert_chain(), true, api); + grpc::experimental::TlsChannelCredentialsOptions options; + if (!private_key.empty() || !cert_chain.empty()) { + options.set_certificate_provider( + std::make_shared( + root_certs, + std::vector{{private_key, cert_chain}})); + } else if (!root_certs.empty()) { + options.set_certificate_provider( + std::make_shared(root_certs)); + } + if (!root_certs.empty()) { + options.watch_root_certs(); + } + if (!private_key.empty() || !cert_chain.empty()) { + options.watch_identity_key_cert_pairs(); + } + if (Runtime::runtimeFeatureEnabled("envoy.reloadable_features.google_grpc_disable_tls_13")) { + options.set_max_tls_version(grpc_tls_version::TLS1_2); + } + return grpc::experimental::TlsCredentials(options); } case envoy::config::core::v3::GrpcService::GoogleGrpc::ChannelCredentials:: CredentialSpecifierCase::kLocalCredentials: { @@ -43,7 +63,11 @@ std::shared_ptr CredsUtility::defaultSslChannelCredent if (creds != nullptr) { return creds; } - return grpc::SslCredentials({}); + grpc::experimental::TlsChannelCredentialsOptions options; + if (Runtime::runtimeFeatureEnabled("envoy.reloadable_features.google_grpc_disable_tls_13")) { + options.set_max_tls_version(grpc_tls_version::TLS1_2); + } + return grpc::experimental::TlsCredentials(options); } std::vector> diff --git a/source/common/runtime/runtime_features.cc b/source/common/runtime/runtime_features.cc index 60d594c96431..607adfb66f05 100644 --- a/source/common/runtime/runtime_features.cc +++ b/source/common/runtime/runtime_features.cc @@ -122,6 +122,10 @@ FALSE_RUNTIME_GUARD(envoy_reloadable_features_refresh_rtt_after_request); // TODO(danzh) false deprecate it once QUICHE has its own enable/disable flag. FALSE_RUNTIME_GUARD(envoy_reloadable_features_quic_reject_all); +// A flag to set the maximum TLS version for google_grpc client to TLS1.2, when needed for +// compliance restrictions. +FALSE_RUNTIME_GUARD(envoy_reloadable_features_google_grpc_disable_tls_13); + // Block of non-boolean flags. Use of int flags is deprecated. Do not add more. ABSL_FLAG(uint64_t, re2_max_program_size_error_level, 100, ""); // NOLINT ABSL_FLAG(uint64_t, re2_max_program_size_warn_level, // NOLINT diff --git a/test/common/grpc/BUILD b/test/common/grpc/BUILD index 6cf74e7f7d7e..0c8cb3380684 100644 --- a/test/common/grpc/BUILD +++ b/test/common/grpc/BUILD @@ -176,6 +176,7 @@ envoy_cc_test( ":grpc_client_integration_test_harness_lib", "//source/common/grpc:async_client_lib", "//source/extensions/grpc_credentials/example:config", + "//test/test_common:test_runtime_lib", ] + envoy_select_google_grpc(["//source/common/grpc:google_async_client_lib"]), ) diff --git a/test/common/grpc/grpc_client_integration_test.cc b/test/common/grpc/grpc_client_integration_test.cc index 3fd32c96d8fc..099d6fa5704c 100644 --- a/test/common/grpc/grpc_client_integration_test.cc +++ b/test/common/grpc/grpc_client_integration_test.cc @@ -5,6 +5,7 @@ #endif +#include "test/test_common/test_runtime.h" #include "test/common/grpc/grpc_client_integration_test_harness.h" using testing::Eq; @@ -409,6 +410,29 @@ TEST_P(GrpcSslClientIntegrationTest, BasicSslRequestWithClientCert) { dispatcher_helper_.runDispatcher(); } +// Validate TLS version mismatch between the client and the server. +TEST_P(GrpcSslClientIntegrationTest, BasicSslRequestHandshakeFailure) { + SKIP_IF_GRPC_CLIENT(ClientType::EnvoyGrpc); + TestScopedRuntime scoped_runtime; + scoped_runtime.mergeValues({{"envoy.reloadable_features.google_grpc_disable_tls_13", "true"}}); + use_server_tls_13_ = true; + initialize(); + auto request = createRequest(empty_metadata_, false); + EXPECT_CALL(*request->child_span_, setTag(Eq(Tracing::Tags::get().GrpcStatusCode), Eq("13"))); + EXPECT_CALL(*request->child_span_, + setTag(Eq(Tracing::Tags::get().Error), Eq(Tracing::Tags::get().True))); + EXPECT_CALL(*request, onFailure(Status::Internal, "", _)).WillOnce(InvokeWithoutArgs([this]() { + dispatcher_helper_.dispatcher_.exit(); + })); + EXPECT_CALL(*request->child_span_, finishSpan()); + FakeRawConnectionPtr fake_connection; + ASSERT_TRUE(fake_upstream_->waitForRawConnection(fake_connection)); + if (fake_connection->connected()) { + ASSERT_TRUE(fake_connection->waitForDisconnect()); + } + dispatcher_helper_.dispatcher_.run(Event::Dispatcher::RunType::Block); +} + #ifdef ENVOY_GOOGLE_GRPC // AccessToken credential validation tests. class GrpcAccessTokenClientIntegrationTest : public GrpcSslClientIntegrationTest { diff --git a/test/common/grpc/grpc_client_integration_test_harness.h b/test/common/grpc/grpc_client_integration_test_harness.h index a30067cb190a..93990a8982ab 100644 --- a/test/common/grpc/grpc_client_integration_test_harness.h +++ b/test/common/grpc/grpc_client_integration_test_harness.h @@ -365,7 +365,8 @@ class GrpcClientIntegrationTest : public GrpcClientIntegrationParamTest { virtual void expectExtraHeaders(FakeStream&) {} - HelloworldRequestPtr createRequest(const TestMetadata& initial_metadata) { + HelloworldRequestPtr createRequest(const TestMetadata& initial_metadata, + bool expect_upstream_request = true) { auto request = std::make_unique(dispatcher_helper_); EXPECT_CALL(*request, onCreateInitialMetadata(_)) .WillOnce(Invoke([&initial_metadata](Http::HeaderMap& headers) { @@ -392,6 +393,10 @@ class GrpcClientIntegrationTest : public GrpcClientIntegrationParamTest { active_span, Http::AsyncClient::RequestOptions()); EXPECT_NE(request->grpc_request_, nullptr); + if (!expect_upstream_request) { + return request; + } + if (!fake_connection_) { AssertionResult result = fake_upstream_->waitForHttpConnection(*dispatcher_, fake_connection_); @@ -526,6 +531,7 @@ class GrpcSslClientIntegrationTest : public GrpcClientIntegrationTest { tls_cert->mutable_private_key()->set_filename( TestEnvironment::runfilesPath("test/config/integration/certs/clientkey.pem")); } + auto cfg = std::make_unique( tls_context, factory_context_); @@ -557,6 +563,13 @@ class GrpcSslClientIntegrationTest : public GrpcClientIntegrationTest { validation_context->mutable_trusted_ca()->set_filename( TestEnvironment::runfilesPath("test/config/integration/certs/cacert.pem")); } + if (use_server_tls_13_) { + auto* tls_params = common_tls_context->mutable_tls_params(); + tls_params->set_tls_minimum_protocol_version( + envoy::extensions::transport_sockets::tls::v3::TlsParameters::TLSv1_3); + tls_params->set_tls_maximum_protocol_version( + envoy::extensions::transport_sockets::tls::v3::TlsParameters::TLSv1_3); + } auto cfg = std::make_unique( tls_context, factory_context_); @@ -568,6 +581,7 @@ class GrpcSslClientIntegrationTest : public GrpcClientIntegrationTest { } bool use_client_cert_{}; + bool use_server_tls_13_{false}; testing::NiceMock factory_context_; }; From 3164ebde91924089f6db4e52dd8993d3edb842b3 Mon Sep 17 00:00:00 2001 From: Sebastian Schepens Date: Fri, 1 Mar 2024 17:45:20 -0300 Subject: [PATCH 07/19] populate histogram summary sample sum Signed-off-by: Sebastian Schepens --- .../stat_sinks/metrics_service/grpc_metrics_service_impl.cc | 1 + .../metrics_service/grpc_metrics_service_impl_test.cc | 2 ++ 2 files changed, 3 insertions(+) diff --git a/source/extensions/stat_sinks/metrics_service/grpc_metrics_service_impl.cc b/source/extensions/stat_sinks/metrics_service/grpc_metrics_service_impl.cc index 2b74663df397..f1f593a83aa6 100644 --- a/source/extensions/stat_sinks/metrics_service/grpc_metrics_service_impl.cc +++ b/source/extensions/stat_sinks/metrics_service/grpc_metrics_service_impl.cc @@ -135,6 +135,7 @@ void MetricsFlusher::flushSummary(io::prometheus::client::MetricFamily& metrics_ quantile->set_value(hist_stats.computedQuantiles()[i]); } summary->set_sample_count(hist_stats.sampleCount()); + summary->set_sample_sum(hist_stats.sampleSum()); } io::prometheus::client::Metric* diff --git a/test/extensions/stats_sinks/metrics_service/grpc_metrics_service_impl_test.cc b/test/extensions/stats_sinks/metrics_service/grpc_metrics_service_impl_test.cc index 6e7dc7425ce0..59ceb061fbd4 100644 --- a/test/extensions/stats_sinks/metrics_service/grpc_metrics_service_impl_test.cc +++ b/test/extensions/stats_sinks/metrics_service/grpc_metrics_service_impl_test.cc @@ -344,6 +344,7 @@ TEST_F(MetricsServiceSinkTest, HistogramEmitModeBoth) { const auto& metric1 = (*metrics)[0].metric(0); EXPECT_TRUE(metric1.has_summary()); + EXPECT_TRUE(metric1.summary().has_sample_sum()); const auto& metric2 = (*metrics)[1].metric(0); EXPECT_TRUE(metric2.has_histogram()); })); @@ -364,6 +365,7 @@ TEST_F(MetricsServiceSinkTest, HistogramEmitModeSummary) { const auto& metric1 = (*metrics)[0].metric(0); EXPECT_TRUE(metric1.has_summary()); + EXPECT_TRUE(metric1.summary().has_sample_sum()); })); sink.flush(snapshot_); } From dfd30809b1714823824f9a012e5921d84caf7ff6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Mar 2024 09:24:01 +0000 Subject: [PATCH 08/19] build(deps): bump distroless/base-nossl-debian12 from `28dc895` to `0e777c6` in /ci (#32652) build(deps): bump distroless/base-nossl-debian12 in /ci Bumps distroless/base-nossl-debian12 from `28dc895` to `0e777c6`. --- updated-dependencies: - dependency-name: distroless/base-nossl-debian12 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: Ryan Northey --- ci/Dockerfile-envoy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/Dockerfile-envoy b/ci/Dockerfile-envoy index b9a043670d90..9e4e156bc75e 100644 --- a/ci/Dockerfile-envoy +++ b/ci/Dockerfile-envoy @@ -58,7 +58,7 @@ COPY --chown=0:0 --chmod=755 \ # STAGE: envoy-distroless -FROM gcr.io/distroless/base-nossl-debian12:nonroot@sha256:28dc8956c04a92ffc192d06c5da69fa747c675ee44043ba18128e747c2f539f5 AS envoy-distroless +FROM gcr.io/distroless/base-nossl-debian12:nonroot@sha256:0e777c69ba810353b9f3f2033280bbe7d029d81fa55760f6eec817ef595aa19c AS envoy-distroless EXPOSE 10000 ENTRYPOINT ["/usr/local/bin/envoy"] CMD ["-c", "/etc/envoy/envoy.yaml"] From 55f034049b22a4cfd85f74bb410e08b2aa0c3372 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Mar 2024 09:53:42 +0000 Subject: [PATCH 09/19] build(deps): bump distroless/base-nossl-debian12 from `0e777c6` to `099c134` in /ci (#32843) build(deps): bump distroless/base-nossl-debian12 in /ci Bumps distroless/base-nossl-debian12 from `0e777c6` to `099c134`. --- updated-dependencies: - dependency-name: distroless/base-nossl-debian12 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: Ryan Northey --- ci/Dockerfile-envoy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/Dockerfile-envoy b/ci/Dockerfile-envoy index 9e4e156bc75e..9c5c824d38c3 100644 --- a/ci/Dockerfile-envoy +++ b/ci/Dockerfile-envoy @@ -58,7 +58,7 @@ COPY --chown=0:0 --chmod=755 \ # STAGE: envoy-distroless -FROM gcr.io/distroless/base-nossl-debian12:nonroot@sha256:0e777c69ba810353b9f3f2033280bbe7d029d81fa55760f6eec817ef595aa19c AS envoy-distroless +FROM gcr.io/distroless/base-nossl-debian12:nonroot@sha256:099c13463fdd2f52d31af8b61f5a991ed8e97bdac529f10b22c4f4ebf0c21c0d AS envoy-distroless EXPOSE 10000 ENTRYPOINT ["/usr/local/bin/envoy"] CMD ["-c", "/etc/envoy/envoy.yaml"] From dbcd32446dee106526e1cc5f7fc7b547e75ba0f6 Mon Sep 17 00:00:00 2001 From: "dependency-envoy[bot]" <148525496+dependency-envoy[bot]@users.noreply.github.com> Date: Wed, 13 Dec 2023 22:59:48 +0000 Subject: [PATCH 10/19] deps: Bump `com_github_nghttp2_nghttp2` -> 1.58.0 (#31361) Signed-off-by: dependency-envoy[bot] <148525496+dependency-envoy[bot]@users.noreply.github.com> Signed-off-by: Ryan Northey --- bazel/repository_locations.bzl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bazel/repository_locations.bzl b/bazel/repository_locations.bzl index 0fff5cd49b19..e16080fb96d5 100644 --- a/bazel/repository_locations.bzl +++ b/bazel/repository_locations.bzl @@ -456,12 +456,12 @@ REPOSITORY_LOCATIONS_SPEC = dict( project_name = "Nghttp2", project_desc = "Implementation of HTTP/2 and its header compression algorithm HPACK in C", project_url = "https://nghttp2.org", - version = "1.57.0", - sha256 = "1e3258453784d3b7e6cc48d0be087b168f8360b5d588c66bfeda05d07ad39ffd", + version = "1.58.0", + sha256 = "9ebdfbfbca164ef72bdf5fd2a94a4e6dfb54ec39d2ef249aeb750a91ae361dfb", strip_prefix = "nghttp2-{version}", urls = ["https://github.com/nghttp2/nghttp2/releases/download/v{version}/nghttp2-{version}.tar.gz"], use_category = ["controlplane", "dataplane_core"], - release_date = "2023-10-10", + release_date = "2023-10-27", cpe = "cpe:2.3:a:nghttp2:nghttp2:*", license = "MIT", license_url = "https://github.com/nghttp2/nghttp2/blob/v{version}/LICENSE", From f389da327416e36ee7020a914209e087d625599e Mon Sep 17 00:00:00 2001 From: "dependency-envoy[bot]" <148525496+dependency-envoy[bot]@users.noreply.github.com> Date: Tue, 23 Jan 2024 12:44:06 +0000 Subject: [PATCH 11/19] deps: Bump `com_github_nghttp2_nghttp2` -> 1.59.0 (#31953) Signed-off-by: dependency-envoy[bot] <148525496+dependency-envoy[bot]@users.noreply.github.com> Co-authored-by: dependency-envoy[bot] <148525496+dependency-envoy[bot]@users.noreply.github.com> Signed-off-by: Ryan Northey --- bazel/repository_locations.bzl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bazel/repository_locations.bzl b/bazel/repository_locations.bzl index e16080fb96d5..4554b7af10cb 100644 --- a/bazel/repository_locations.bzl +++ b/bazel/repository_locations.bzl @@ -456,12 +456,12 @@ REPOSITORY_LOCATIONS_SPEC = dict( project_name = "Nghttp2", project_desc = "Implementation of HTTP/2 and its header compression algorithm HPACK in C", project_url = "https://nghttp2.org", - version = "1.58.0", - sha256 = "9ebdfbfbca164ef72bdf5fd2a94a4e6dfb54ec39d2ef249aeb750a91ae361dfb", + version = "1.59.0", + sha256 = "90fd27685120404544e96a60ed40398a3457102840c38e7215dc6dec8684470f", strip_prefix = "nghttp2-{version}", urls = ["https://github.com/nghttp2/nghttp2/releases/download/v{version}/nghttp2-{version}.tar.gz"], use_category = ["controlplane", "dataplane_core"], - release_date = "2023-10-27", + release_date = "2024-01-21", cpe = "cpe:2.3:a:nghttp2:nghttp2:*", license = "MIT", license_url = "https://github.com/nghttp2/nghttp2/blob/v{version}/LICENSE", From 776c3d75b396e0af81a7729f49622af6a8381269 Mon Sep 17 00:00:00 2001 From: phlax Date: Thu, 14 Mar 2024 20:41:52 +0000 Subject: [PATCH 12/19] ci: Disable windows (#32904) Signed-off-by: Ryan Northey --- .github/config.yml | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/.github/config.yml b/.github/config.yml index 50a28027053d..a9dde4d03896 100644 --- a/.github/config.yml +++ b/.github/config.yml @@ -80,27 +80,8 @@ checks: - publish - verify required: true - windows: - name: Envoy/Windows - required: true - on-run: - - build-windows run: - build-windows: - paths: - - .bazelrc - - .bazelversion - - .github/config.yml - - api/**/* - - bazel/**/* - - ci/**/* - - configs/**/* - - contrib/**/* - - envoy/**/* - - source/**/* - - test/**/* - - VERSION.txt build-macos: paths: - .bazelrc From f7d7ae74f17474eadd15c20b3e8f6d3037795c2c Mon Sep 17 00:00:00 2001 From: Sean Killeen Date: Thu, 4 Apr 2024 04:36:55 -0400 Subject: [PATCH 13/19] H/2: discard Host header when :authority is present (#30005) Discard the Host header if the :authority header was received to bring Envoy into compliance with https://www.rfc-editor.org/rfc/rfc9113#section-8.3.1 This behavioral change can be reverted by setting runtime flag envoy.reloadable_features.http2_discard_host_header to false. --------- Signed-off-by: Yan Avlasov Signed-off-by: Sean Killeen --- changelogs/current.yaml | 5 ++ source/common/http/http2/codec_impl.cc | 12 +++ source/common/runtime/runtime_features.cc | 1 + test/common/http/http2/http2_frame.h | 6 +- .../multiplexed_integration_test.cc | 77 +++++++++++++++++++ 5 files changed, 98 insertions(+), 3 deletions(-) diff --git a/changelogs/current.yaml b/changelogs/current.yaml index 2b8dc99df2e0..8002c795d977 100644 --- a/changelogs/current.yaml +++ b/changelogs/current.yaml @@ -2,6 +2,11 @@ date: Pending behavior_changes: # *Changes that are expected to cause an incompatibility if applicable; deployment changes are likely required* +- area: http2 + change: | + Discard the ``Host`` header if the ``:authority`` header was received to bring Envoy into compliance with + https://www.rfc-editor.org/rfc/rfc9113#section-8.3.1 This behavioral change can be reverted by setting runtime flag + ``envoy.reloadable_features.http2_discard_host_header`` to false. minor_behavior_changes: # *Changes that may cause incompatibilities for some users, but should not for most* diff --git a/source/common/http/http2/codec_impl.cc b/source/common/http/http2/codec_impl.cc index ad7c29b423dc..fb4f1f9215fd 100644 --- a/source/common/http/http2/codec_impl.cc +++ b/source/common/http/http2/codec_impl.cc @@ -2110,6 +2110,18 @@ int ServerConnectionImpl::onHeader(const nghttp2_frame* frame, HeaderString&& na // For a server connection, we should never get push promise frames. ASSERT(frame->hd.type == NGHTTP2_HEADERS); ASSERT(frame->headers.cat == NGHTTP2_HCAT_REQUEST || frame->headers.cat == NGHTTP2_HCAT_HEADERS); + if (Runtime::runtimeFeatureEnabled("envoy.reloadable_features.http2_discard_host_header")) { + StreamImpl* stream = getStreamUnchecked(frame->hd.stream_id); + if (stream && name == static_cast(Http::Headers::get().HostLegacy)) { + // Check if there is already the :authority header + const auto result = stream->headers().get(Http::Headers::get().Host); + if (!result.empty()) { + // Discard the host header value + return 0; + } + // Otherwise use host value as :authority + } + } return saveHeader(frame, std::move(name), std::move(value)); } diff --git a/source/common/runtime/runtime_features.cc b/source/common/runtime/runtime_features.cc index 607adfb66f05..c1d28ac747d4 100644 --- a/source/common/runtime/runtime_features.cc +++ b/source/common/runtime/runtime_features.cc @@ -47,6 +47,7 @@ RUNTIME_GUARD(envoy_reloadable_features_format_ports_as_numbers); RUNTIME_GUARD(envoy_reloadable_features_handle_uppercase_scheme); RUNTIME_GUARD(envoy_reloadable_features_http1_allow_codec_error_response_after_1xx_headers); RUNTIME_GUARD(envoy_reloadable_features_http2_decode_metadata_with_quiche); +RUNTIME_GUARD(envoy_reloadable_features_http2_discard_host_header); RUNTIME_GUARD(envoy_reloadable_features_http2_validate_authority_with_quiche); RUNTIME_GUARD(envoy_reloadable_features_http_allow_partial_urls_in_referer); RUNTIME_GUARD(envoy_reloadable_features_http_ext_auth_failure_mode_allow_header_add); diff --git a/test/common/http/http2/http2_frame.h b/test/common/http/http2/http2_frame.h index 6349f5d94d84..0789fc5bf11a 100644 --- a/test/common/http/http2/http2_frame.h +++ b/test/common/http/http2/http2_frame.h @@ -260,6 +260,9 @@ class Http2Frame { ASSERT(size() >= HeaderSize); setPayloadSize(size() - HeaderSize); } + // Headers are directly encoded + void appendStaticHeader(StaticHeaderIndex index); + void appendHeaderWithoutIndexing(StaticHeaderIndex index, absl::string_view value); private: void buildHeader(Type type, uint32_t payload_size = 0, uint8_t flags = 0, uint32_t stream_id = 0); @@ -277,9 +280,6 @@ class Http2Frame { std::copy(data.begin(), data.end(), data_.begin() + 9); } - // Headers are directly encoded - void appendStaticHeader(StaticHeaderIndex index); - void appendHeaderWithoutIndexing(StaticHeaderIndex index, absl::string_view value); void appendEmptyHeader(); DataContainer data_; diff --git a/test/integration/multiplexed_integration_test.cc b/test/integration/multiplexed_integration_test.cc index f2e7df6b2b98..c2c9dc5e5486 100644 --- a/test/integration/multiplexed_integration_test.cc +++ b/test/integration/multiplexed_integration_test.cc @@ -2129,7 +2129,84 @@ TEST_P(Http2FrameIntegrationTest, AccessLogOfWireBytesIfResponseSizeGreaterThanW // Cleanup. tcp_client_->close(); } +TEST_P(Http2FrameIntegrationTest, HostDifferentFromAuthority) { + beginSession(); + + uint32_t request_idx = 0; + auto request = Http2Frame::makeRequest(Http2Frame::makeClientStreamId(request_idx), + "one.example.com", "/path", {{"host", "two.example.com"}}); + sendFrame(request); + + waitForNextUpstreamRequest(); + EXPECT_EQ(upstream_request_->headers().getHostValue(), "one.example.com"); + upstream_request_->encodeHeaders(default_response_headers_, true); + auto frame = readFrame(); + EXPECT_EQ(Http2Frame::Type::Headers, frame.type()); + EXPECT_EQ(Http2Frame::ResponseStatus::Ok, frame.responseStatus()); + tcp_client_->close(); +} + +TEST_P(Http2FrameIntegrationTest, HostSameAsAuthority) { + beginSession(); + + uint32_t request_idx = 0; + auto request = Http2Frame::makeRequest(Http2Frame::makeClientStreamId(request_idx), + "one.example.com", "/path", {{"host", "one.example.com"}}); + sendFrame(request); + + waitForNextUpstreamRequest(); + EXPECT_EQ(upstream_request_->headers().getHostValue(), "one.example.com"); + upstream_request_->encodeHeaders(default_response_headers_, true); + auto frame = readFrame(); + EXPECT_EQ(Http2Frame::Type::Headers, frame.type()); + EXPECT_EQ(Http2Frame::ResponseStatus::Ok, frame.responseStatus()); + tcp_client_->close(); +} + +TEST_P(Http2FrameIntegrationTest, HostConcatenatedWithAuthorityWithOverride) { + config_helper_.addRuntimeOverride("envoy.reloadable_features.http2_discard_host_header", "false"); + beginSession(); + + uint32_t request_idx = 0; + auto request = Http2Frame::makeRequest(Http2Frame::makeClientStreamId(request_idx), + "one.example.com", "/path", {{"host", "two.example.com"}}); + sendFrame(request); + + waitForNextUpstreamRequest(); + EXPECT_EQ(upstream_request_->headers().getHostValue(), "one.example.com,two.example.com"); + upstream_request_->encodeHeaders(default_response_headers_, true); + auto frame = readFrame(); + EXPECT_EQ(Http2Frame::Type::Headers, frame.type()); + EXPECT_EQ(Http2Frame::ResponseStatus::Ok, frame.responseStatus()); + tcp_client_->close(); +} + +// All HTTP/2 static headers must be before non-static headers. +// Verify that codecs validate this. +TEST_P(Http2FrameIntegrationTest, HostBeforeAuthorityIsRejected) { +#ifdef ENVOY_ENABLE_UHV + // TODO(yanavlasov): fix this check for oghttp2 in UHV mode. + return; +#endif + beginSession(); + Http2Frame request = Http2Frame::makeEmptyHeadersFrame(Http2Frame::makeClientStreamId(0), + Http2Frame::HeadersFlags::EndHeaders); + request.appendStaticHeader(Http2Frame::StaticHeaderIndex::MethodPost); + request.appendStaticHeader(Http2Frame::StaticHeaderIndex::SchemeHttps); + request.appendHeaderWithoutIndexing(Http2Frame::StaticHeaderIndex::Path, "/path"); + // Add the `host` header before `:authority` + request.appendHeaderWithoutIndexing({"host", "two.example.com"}); + request.appendHeaderWithoutIndexing(Http2Frame::StaticHeaderIndex::Authority, "one.example.com"); + request.adjustPayloadSize(); + + sendFrame(request); + + // By default codec treats stream errors as protocol errors and closes the connection. + tcp_client_->waitForDisconnect(); + tcp_client_->close(); + EXPECT_EQ(1, test_server_->counter("http.config_test.downstream_cx_protocol_error")->value()); +} TEST_P(Http2FrameIntegrationTest, MultipleHeaderOnlyRequests) { const int kRequestsSentPerIOCycle = 20; autonomous_upstream_ = true; From c473913397454b4d0626a90f0fe2b0e9614a0d87 Mon Sep 17 00:00:00 2001 From: Ryan Northey Date: Wed, 3 Apr 2024 17:49:28 +0100 Subject: [PATCH 14/19] docker/release: Update Ubuntu images (80ef4a44) Signed-off-by: Ryan Northey --- ci/Dockerfile-envoy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/Dockerfile-envoy b/ci/Dockerfile-envoy index 9c5c824d38c3..1752d328fe0f 100644 --- a/ci/Dockerfile-envoy +++ b/ci/Dockerfile-envoy @@ -1,5 +1,5 @@ ARG BUILD_OS=ubuntu -ARG BUILD_TAG=20.04@sha256:bb1c41682308d7040f74d103022816d41c50d7b0c89e9d706a74b4e548636e54 +ARG BUILD_TAG=20.04@sha256:80ef4a44043dec4490506e6cc4289eeda2d106a70148b74b5ae91ee670e9c35d ARG ENVOY_VRP_BASE_IMAGE=envoy-base From 8754c0ffe87c36906103815ce8d5434fc8b9bcd0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 4 Apr 2024 09:16:32 +0100 Subject: [PATCH 15/19] build(deps): bump distroless/base-nossl-debian12 from `099c134` to `0cf184c` in /ci (#33282) build(deps): bump distroless/base-nossl-debian12 in /ci Bumps distroless/base-nossl-debian12 from `099c134` to `0cf184c`. --- updated-dependencies: - dependency-name: distroless/base-nossl-debian12 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: Ryan Northey --- ci/Dockerfile-envoy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/Dockerfile-envoy b/ci/Dockerfile-envoy index 1752d328fe0f..396e1fb1d770 100644 --- a/ci/Dockerfile-envoy +++ b/ci/Dockerfile-envoy @@ -58,7 +58,7 @@ COPY --chown=0:0 --chmod=755 \ # STAGE: envoy-distroless -FROM gcr.io/distroless/base-nossl-debian12:nonroot@sha256:099c13463fdd2f52d31af8b61f5a991ed8e97bdac529f10b22c4f4ebf0c21c0d AS envoy-distroless +FROM gcr.io/distroless/base-nossl-debian12:nonroot@sha256:0cf184cfdb9ac2878822b15b8917fae5d42fba26da654cd75ab3ed34add0737f AS envoy-distroless EXPOSE 10000 ENTRYPOINT ["/usr/local/bin/envoy"] CMD ["-c", "/etc/envoy/envoy.yaml"] From 95d92b4a15ddbf588b949999a75fdca289a96550 Mon Sep 17 00:00:00 2001 From: Ryan Northey Date: Thu, 4 Apr 2024 12:08:41 +0100 Subject: [PATCH 16/19] deps/CVE: Fix (nghttp2) CVE-2024-30255 Signed-off-by: Ryan Northey --- bazel/foreign_cc/nghttp2.patch | 168 +++++++++++++++++++++++++++++++++ 1 file changed, 168 insertions(+) diff --git a/bazel/foreign_cc/nghttp2.patch b/bazel/foreign_cc/nghttp2.patch index d1cbab6356e5..511e2a2e4b29 100644 --- a/bazel/foreign_cc/nghttp2.patch +++ b/bazel/foreign_cc/nghttp2.patch @@ -14,3 +14,171 @@ diff -u -r a/CMakeLists.txt b/CMakeLists.txt endif() # AC_TYPE_UINT8_T # AC_TYPE_UINT16_T +diff --git a/doc/Makefile.am b/doc/Makefile.am +index 7d7f31c6..ce50d89e 100644 +--- a/doc/Makefile.am ++++ b/doc/Makefile.am +@@ -74,6 +74,7 @@ APIDOCS= \ + nghttp2_option_set_peer_max_concurrent_streams.rst \ + nghttp2_option_set_server_fallback_rfc7540_priorities.rst \ + nghttp2_option_set_user_recv_extension_type.rst \ ++ nghttp2_option_set_max_continuations.rst \ + nghttp2_option_set_max_outbound_ack.rst \ + nghttp2_option_set_max_settings.rst \ + nghttp2_option_set_stream_reset_rate_limit.rst \ +diff --git a/lib/includes/nghttp2/nghttp2.h b/lib/includes/nghttp2/nghttp2.h +index 7910db23..a54efbfd 100644 +--- a/lib/includes/nghttp2/nghttp2.h ++++ b/lib/includes/nghttp2/nghttp2.h +@@ -440,7 +440,12 @@ typedef enum { + * exhaustion on server side to send these frames forever and does + * not read network. + */ +- NGHTTP2_ERR_FLOODED = -904 ++ NGHTTP2_ERR_FLOODED = -904, ++ /** ++ * When a local endpoint receives too many CONTINUATION frames ++ * following a HEADER frame. ++ */ ++ NGHTTP2_ERR_TOO_MANY_CONTINUATIONS = -905, + } nghttp2_error; + + /** +@@ -2773,6 +2778,17 @@ NGHTTP2_EXTERN void + nghttp2_option_set_stream_reset_rate_limit(nghttp2_option *option, + uint64_t burst, uint64_t rate); + ++/** ++ * @function ++ * ++ * This function sets the maximum number of CONTINUATION frames ++ * following an incoming HEADER frame. If more than those frames are ++ * received, the remote endpoint is considered to be misbehaving and ++ * session will be closed. The default value is 8. ++ */ ++NGHTTP2_EXTERN void nghttp2_option_set_max_continuations(nghttp2_option *option, ++ size_t val); ++ + /** + * @function + * +diff --git a/lib/nghttp2_helper.c b/lib/nghttp2_helper.c +index 93dd4754..b3563d98 100644 +--- a/lib/nghttp2_helper.c ++++ b/lib/nghttp2_helper.c +@@ -336,6 +336,8 @@ const char *nghttp2_strerror(int error_code) { + "closed"; + case NGHTTP2_ERR_TOO_MANY_SETTINGS: + return "SETTINGS frame contained more than the maximum allowed entries"; ++ case NGHTTP2_ERR_TOO_MANY_CONTINUATIONS: ++ return "Too many CONTINUATION frames following a HEADER frame"; + default: + return "Unknown error code"; + } +diff --git a/lib/nghttp2_option.c b/lib/nghttp2_option.c +index 43d4e952..53144b9b 100644 +--- a/lib/nghttp2_option.c ++++ b/lib/nghttp2_option.c +@@ -150,3 +150,8 @@ void nghttp2_option_set_stream_reset_rate_limit(nghttp2_option *option, + option->stream_reset_burst = burst; + option->stream_reset_rate = rate; + } ++ ++void nghttp2_option_set_max_continuations(nghttp2_option *option, size_t val) { ++ option->opt_set_mask |= NGHTTP2_OPT_MAX_CONTINUATIONS; ++ option->max_continuations = val; ++} +diff --git a/lib/nghttp2_option.h b/lib/nghttp2_option.h +index 2259e184..c89cb97f 100644 +--- a/lib/nghttp2_option.h ++++ b/lib/nghttp2_option.h +@@ -71,6 +71,7 @@ typedef enum { + NGHTTP2_OPT_SERVER_FALLBACK_RFC7540_PRIORITIES = 1 << 13, + NGHTTP2_OPT_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION = 1 << 14, + NGHTTP2_OPT_STREAM_RESET_RATE_LIMIT = 1 << 15, ++ NGHTTP2_OPT_MAX_CONTINUATIONS = 1 << 16, + } nghttp2_option_flag; + + /** +@@ -98,6 +99,10 @@ struct nghttp2_option { + * NGHTTP2_OPT_MAX_SETTINGS + */ + size_t max_settings; ++ /** ++ * NGHTTP2_OPT_MAX_CONTINUATIONS ++ */ ++ size_t max_continuations; + /** + * Bitwise OR of nghttp2_option_flag to determine that which fields + * are specified. +diff --git a/lib/nghttp2_session.c b/lib/nghttp2_session.c +index ce21caf9..18949528 100644 +--- a/lib/nghttp2_session.c ++++ b/lib/nghttp2_session.c +@@ -496,6 +496,7 @@ static int session_new(nghttp2_session **session_ptr, + (*session_ptr)->max_send_header_block_length = NGHTTP2_MAX_HEADERSLEN; + (*session_ptr)->max_outbound_ack = NGHTTP2_DEFAULT_MAX_OBQ_FLOOD_ITEM; + (*session_ptr)->max_settings = NGHTTP2_DEFAULT_MAX_SETTINGS; ++ (*session_ptr)->max_continuations = NGHTTP2_DEFAULT_MAX_CONTINUATIONS; + + if (option) { + if ((option->opt_set_mask & NGHTTP2_OPT_NO_AUTO_WINDOW_UPDATE) && +@@ -584,6 +585,10 @@ static int session_new(nghttp2_session **session_ptr, + option->stream_reset_burst, + option->stream_reset_rate); + } ++ ++ if (option->opt_set_mask & NGHTTP2_OPT_MAX_CONTINUATIONS) { ++ (*session_ptr)->max_continuations = option->max_continuations; ++ } + } + + rv = nghttp2_hd_deflate_init2(&(*session_ptr)->hd_deflater, +@@ -6778,6 +6783,8 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in, + } + } + session_inbound_frame_reset(session); ++ ++ session->num_continuations = 0; + } + break; + } +@@ -6899,6 +6906,10 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in, + } + #endif /* DEBUGBUILD */ + ++ if (++session->num_continuations > session->max_continuations) { ++ return NGHTTP2_ERR_TOO_MANY_CONTINUATIONS; ++ } ++ + readlen = inbound_frame_buf_read(iframe, in, last); + in += readlen; + +diff --git a/lib/nghttp2_session.h b/lib/nghttp2_session.h +index b119329a..ef8f7b27 100644 +--- a/lib/nghttp2_session.h ++++ b/lib/nghttp2_session.h +@@ -110,6 +110,10 @@ typedef struct { + #define NGHTTP2_DEFAULT_STREAM_RESET_BURST 1000 + #define NGHTTP2_DEFAULT_STREAM_RESET_RATE 33 + ++/* The default max number of CONTINUATION frames following an incoming ++ HEADER frame. */ ++#define NGHTTP2_DEFAULT_MAX_CONTINUATIONS 8 ++ + /* Internal state when receiving incoming frame */ + typedef enum { + /* Receiving frame header */ +@@ -290,6 +294,12 @@ struct nghttp2_session { + size_t max_send_header_block_length; + /* The maximum number of settings accepted per SETTINGS frame. */ + size_t max_settings; ++ /* The maximum number of CONTINUATION frames following an incoming ++ HEADER frame. */ ++ size_t max_continuations; ++ /* The number of CONTINUATION frames following an incoming HEADER ++ frame. This variable is reset when END_HEADERS flag is seen. */ ++ size_t num_continuations; + /* Next Stream ID. Made unsigned int to detect >= (1 << 31). */ + uint32_t next_stream_id; + /* The last stream ID this session initiated. For client session, From 8a6177740b518055b0cf16719b76c4c1794b6757 Mon Sep 17 00:00:00 2001 From: Yan Avlasov Date: Wed, 3 Apr 2024 19:24:35 +0000 Subject: [PATCH 17/19] Update Envoy to use the patch Signed-off-by: Yan Avlasov Signed-off-by: Ryan Northey --- source/common/http/http2/codec_impl.cc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/source/common/http/http2/codec_impl.cc b/source/common/http/http2/codec_impl.cc index fb4f1f9215fd..ab4d5d3b9184 100644 --- a/source/common/http/http2/codec_impl.cc +++ b/source/common/http/http2/codec_impl.cc @@ -1812,6 +1812,11 @@ ConnectionImpl::Http2Options::Http2Options( // on this mitigation, set back to the old 10K number to avoid any changes in the HTTP/2 codec // behavior. nghttp2_option_set_max_outbound_ack(options_, 10000); + + // nghttp2 REQUIRES setting max number of CONTINUATION frames. + // 1024 is chosen to accommodate Envoy's 8Mb max limit of max_request_headers_kb + // in both headers and trailers + nghttp2_option_set_max_continuations(options_, 1024); } ConnectionImpl::Http2Options::~Http2Options() { nghttp2_option_del(options_); } @@ -1826,6 +1831,11 @@ ConnectionImpl::ClientHttp2Options::ClientHttp2Options( // TODO(PiotrSikora): remove this once multiple upstream connections or queuing are implemented. nghttp2_option_set_peer_max_concurrent_streams( options_, ::Envoy::Http2::Utility::OptionsLimits::DEFAULT_MAX_CONCURRENT_STREAMS); + + // nghttp2 REQUIRES setting max number of CONTINUATION frames. + // 1024 is chosen to accommodate Envoy's 8Mb max limit of max_request_headers_kb + // in both headers and trailers + nghttp2_option_set_max_continuations(options_, 1024); } void ConnectionImpl::dumpState(std::ostream& os, int indent_level) const { From dacf7beddfdf3c808413aa028d6862a474ed4fa7 Mon Sep 17 00:00:00 2001 From: Ryan Northey Date: Thu, 4 Apr 2024 11:53:31 +0100 Subject: [PATCH 18/19] changelogs: Add changelog for CVE-2024-30255 https://github.com/envoyproxy/envoy/security/advisories/GHSA-j654-3ccm-vfmm Signed-off-by: Ryan Northey --- changelogs/current.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/changelogs/current.yaml b/changelogs/current.yaml index 8002c795d977..a154c73f0916 100644 --- a/changelogs/current.yaml +++ b/changelogs/current.yaml @@ -13,6 +13,9 @@ minor_behavior_changes: bug_fixes: # *Changes expected to improve the state of the world and are unlikely to have negative effects* +- area: http2 + change: | + Update nghttp2 to resolve CVE-2024-30255 (https://github.com/envoyproxy/envoy/security/advisories/GHSA-j654-3ccm-vfmm). removed_config_or_runtime: # *Normally occurs at the end of the* :ref:`deprecation period ` From 9134d6a65e5c2c714d503807eb31a8490471fc5f Mon Sep 17 00:00:00 2001 From: Ryan Northey Date: Thu, 4 Apr 2024 12:00:12 +0000 Subject: [PATCH 19/19] repo: Release v1.27.4 **Summary of changes**: - Patch nghttp2 to resolve [CVE-2024-30255](https://github.com/envoyproxy/envoy/security/advisories/GHSA-j654-3ccm-vfmm) - Assorted fixes **Docker images**: https://hub.docker.com/r/envoyproxy/envoy/tags?page=1&name=v1.27.4 **Docs**: https://www.envoyproxy.io/docs/envoy/v1.27.4/ **Release notes**: https://www.envoyproxy.io/docs/envoy/v1.27.4/version_history/v1.27/v1.27.4 **Full changelog**: https://github.com/envoyproxy/envoy/compare/v1.27.3...v1.27.4 Signed-off-by: Ryan Northey Signed-off-by: Yan Avlasov --- VERSION.txt | 2 +- changelogs/1.26.8.yaml | 13 ++++++++ changelogs/1.27.3.yaml | 52 +++++++++++++++++++++++++++++ changelogs/current.yaml | 12 +------ docs/inventories/v1.26/objects.inv | Bin 153965 -> 153979 bytes docs/inventories/v1.27/objects.inv | Bin 159876 -> 159932 bytes docs/versions.yaml | 4 +-- 7 files changed, 69 insertions(+), 14 deletions(-) create mode 100644 changelogs/1.26.8.yaml create mode 100644 changelogs/1.27.3.yaml diff --git a/VERSION.txt b/VERSION.txt index 30eedfa5bbb6..d6201580edb4 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -1.27.4-dev +1.27.4 diff --git a/changelogs/1.26.8.yaml b/changelogs/1.26.8.yaml new file mode 100644 index 000000000000..a59f0acb0ad0 --- /dev/null +++ b/changelogs/1.26.8.yaml @@ -0,0 +1,13 @@ +date: April 4, 2024 + +bug_fixes: +- area: http2 + change: | + Update nghttp2 to resolve CVE-2024-30255 (https://github.com/envoyproxy/envoy/security/advisories/GHSA-j654-3ccm-vfmm). + +new_features: +- area: google_grpc + change: | + Added an off-by-default runtime flag + ``envoy.reloadable_features.google_grpc_disable_tls_13`` to disable TLSv1.3 + usage by gRPC SDK for ``google_grpc`` services. diff --git a/changelogs/1.27.3.yaml b/changelogs/1.27.3.yaml new file mode 100644 index 000000000000..a67d0b6cabb2 --- /dev/null +++ b/changelogs/1.27.3.yaml @@ -0,0 +1,52 @@ +date: February 9, 2024 + +minor_behavior_changes: +- area: access_log + change: | + When emitting grpc logs, only downstream filter state was used. Now, both downstream and upstream filter states will be tried + to find the keys configured in filter_state_objects_to_log. + +bug_fixes: +- area: buffer + change: | + Fixed a bug (https://github.com/envoyproxy/envoy/issues/28760) that the internal listener causes an undefined + behavior due to the unintended release of the buffer memory. +- area: http + change: | + Fixed recursion when HTTP connection is disconnected due to a high number of premature resets. +- area: grpc + change: | + Fixed a bug in gRPC async client cache which intermittently causes CPU spikes due to busy loop in timer expiration. +- area: tracing + change: | + Fixed a bug where Datadog spans tagged as errors would not have the appropriate error property set. +- area: tracing + change: | + Fixed a bug where child spans produced by the Datadog tracer would have an incorrect operation name. +- area: tracing + change: | + Fixed a bug that caused the Datadog tracing extension to drop traces that + should be kept on account of an extracted sampling decision. +- area: proxy protocol + change: | + fixed a crash when Envoy is configured for PROXY protocol on both a listener and cluster, and the listener receives + a PROXY protocol header with address type LOCAL (typically used for health checks). +- area: proxy_protocol + change: | + Fix crash due to uncaught exception when the operating system does not support an address type (such as IPv6) that is + received in a proxy protocol header. Connections will instead be dropped/reset. +- area: proxy_protocol + change: | + Fixed a bug where TLVs with non utf8 characters were inserted as protobuf values into filter metadata circumventing + ext_authz checks when ``failure_mode_allow`` is set to ``true``. +- area: tls + change: | + Fix crash due to uncaught exception when the operating system does not support an address type (such as IPv6) that is + received in an mTLS client cert IP SAN. These SANs will be ignored. This applies only when using formatter + ``%DOWNSTREAM_PEER_IP_SAN%``. +- area: http + change: | + Fixed crash when HTTP request idle and per try timeouts occurs within backoff interval. +- area: url matching + change: | + Fixed excessive CPU utilization when using regex URL template matcher. diff --git a/changelogs/current.yaml b/changelogs/current.yaml index a154c73f0916..73d73f7b7a33 100644 --- a/changelogs/current.yaml +++ b/changelogs/current.yaml @@ -1,30 +1,20 @@ -date: Pending +date: April 4, 2024 behavior_changes: -# *Changes that are expected to cause an incompatibility if applicable; deployment changes are likely required* - area: http2 change: | Discard the ``Host`` header if the ``:authority`` header was received to bring Envoy into compliance with https://www.rfc-editor.org/rfc/rfc9113#section-8.3.1 This behavioral change can be reverted by setting runtime flag ``envoy.reloadable_features.http2_discard_host_header`` to false. -minor_behavior_changes: -# *Changes that may cause incompatibilities for some users, but should not for most* - bug_fixes: -# *Changes expected to improve the state of the world and are unlikely to have negative effects* - area: http2 change: | Update nghttp2 to resolve CVE-2024-30255 (https://github.com/envoyproxy/envoy/security/advisories/GHSA-j654-3ccm-vfmm). -removed_config_or_runtime: -# *Normally occurs at the end of the* :ref:`deprecation period ` - new_features: - area: google_grpc change: | Added an off-by-default runtime flag ``envoy.reloadable_features.google_grpc_disable_tls_13`` to disable TLSv1.3 usage by gRPC SDK for ``google_grpc`` services. - -deprecated: diff --git a/docs/inventories/v1.26/objects.inv b/docs/inventories/v1.26/objects.inv index 26b06951df94722c60592253d264b2378a4075bd..e8c220301cff02a790bcb7e6cbc12c9d371cbe41 100644 GIT binary patch delta 18883 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 Cts)Ho delta 18862 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 B*#?+6g3KlzO>{813%9cx&= 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 delta 19228 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 diff --git a/docs/versions.yaml b/docs/versions.yaml index 91b80a86fe85..4be885fd2e54 100644 --- a/docs/versions.yaml +++ b/docs/versions.yaml @@ -19,5 +19,5 @@ "1.23": 1.23.12 "1.24": 1.24.12 "1.25": 1.25.11 -"1.26": 1.26.7 -"1.27": 1.27.2 +"1.26": 1.26.8 +"1.27": 1.27.3