diff --git a/backport-CVE-2024-11407.patch b/backport-CVE-2024-11407.patch new file mode 100644 index 0000000000000000000000000000000000000000..8c45b116842eae0636f80df0b8d0ad7f3ad1d003 --- /dev/null +++ b/backport-CVE-2024-11407.patch @@ -0,0 +1,28 @@ +From e9046b2bbebc0cb7f5dc42008f807f6c7e98e791 Mon Sep 17 00:00:00 2001 +From: Vignesh Babu +Date: Thu, 12 Sep 2024 11:13:45 -0700 +Subject: [PATCH] [EventEngine] Fix bug in Tx0cp code path in posix endpoint. + +This fix ensures that the iov_base pointers point to the right address. + +PiperOrigin-RevId: 673923651 + +Conflict: NA +Reference: https://github.com/grpc/grpc/commit/e9046b2bbebc0cb7f5dc42008f807f6c7e98e791 +--- + src/core/lib/event_engine/posix_engine/posix_endpoint.cc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/core/lib/event_engine/posix_engine/posix_endpoint.cc b/src/core/lib/event_engine/posix_engine/posix_endpoint.cc +index 7634bb1334b81..c5708db02c57a 100644 +--- a/src/core/lib/event_engine/posix_engine/posix_endpoint.cc ++++ b/src/core/lib/event_engine/posix_engine/posix_endpoint.cc +@@ -236,7 +236,7 @@ msg_iovlen_type TcpZerocopySendRecord::PopulateIovs(size_t* unwind_slice_idx, + iov_size++) { + MutableSlice& slice = internal::SliceCast( + buf_.MutableSliceAt(out_offset_.slice_idx)); +- iov[iov_size].iov_base = slice.begin(); ++ iov[iov_size].iov_base = slice.begin() + out_offset_.byte_idx; + iov[iov_size].iov_len = slice.length() - out_offset_.byte_idx; + *sending_length += iov[iov_size].iov_len; + ++(out_offset_.slice_idx); diff --git a/backport-CVE-2024-7246-chttp2-Fix-a-bug-in-hpack-error-handling.patch b/backport-CVE-2024-7246-chttp2-Fix-a-bug-in-hpack-error-handling.patch new file mode 100644 index 0000000000000000000000000000000000000000..66d1caa805793c3d7c59e5c9b829b933b2ee14fd --- /dev/null +++ b/backport-CVE-2024-7246-chttp2-Fix-a-bug-in-hpack-error-handling.patch @@ -0,0 +1,414 @@ +From 88b1244fd43e81860baa60cc7fb3945a2cca0d11 Mon Sep 17 00:00:00 2001 +From: Craig Tiller +Date: Thu, 1 Aug 2024 13:02:27 -0700 +Subject: [PATCH] [v1.60] [chttp2] Fix a bug in hpack error handling (#37361) + +PiperOrigin-RevId: 657234128 +PiperOrigin-RevId: 658458047 + +Conflict:NA +Reference:https://github.com/grpc/grpc/commit/88b1244fd43e81860baa60cc7fb3945a2cca0d11 +--- + .../chttp2/transport/hpack_parser.cc | 63 +++++++------ + .../transport/chttp2/transport/hpack_parser.h | 2 + + .../transport/chttp2/hpack_parser_test.cc | 89 ++++++++++++++++--- + .../transport/chttp2/hpack_sync_fuzzer.cc | 62 +++++++++++++ + .../transport/chttp2/hpack_sync_fuzzer.proto | 3 + + 5 files changed, 179 insertions(+), 40 deletions(-) + +diff --git a/src/core/ext/transport/chttp2/transport/hpack_parser.cc b/src/core/ext/transport/chttp2/transport/hpack_parser.cc +index 31bf46456f..f2fe80c504 100644 +--- a/src/core/ext/transport/chttp2/transport/hpack_parser.cc ++++ b/src/core/ext/transport/chttp2/transport/hpack_parser.cc +@@ -91,12 +91,14 @@ constexpr Base64InverseTable kBase64InverseTable; + class HPackParser::Input { + public: + Input(grpc_slice_refcount* current_slice_refcount, const uint8_t* begin, +- const uint8_t* end, absl::BitGenRef bitsrc, HpackParseResult& error) ++ const uint8_t* end, absl::BitGenRef bitsrc, ++ HpackParseResult& frame_error, HpackParseResult& field_error) + : current_slice_refcount_(current_slice_refcount), + begin_(begin), + end_(end), + frontier_(begin), +- error_(error), ++ frame_error_(frame_error), ++ field_error_(field_error), + bitsrc_(bitsrc) {} + + // If input is backed by a slice, retrieve its refcount. If not, return +@@ -215,14 +217,18 @@ class HPackParser::Input { + + // Check if we saw an EOF + bool eof_error() const { +- return min_progress_size_ != 0 || error_.connection_error(); ++ return min_progress_size_ != 0 || frame_error_.connection_error(); ++ } ++ ++ // Reset the field error to be ok ++ void ClearFieldError() { ++ if (field_error_.ok()) return; ++ field_error_ = HpackParseResult(); + } + + // Minimum number of bytes to unstuck the current parse + size_t min_progress_size() const { return min_progress_size_; } + +- bool has_error() const { return !error_.ok(); } +- + // Set the current error - tweaks the error to include a stream id so that + // chttp2 does not close the connection. + // Intended for errors that are specific to a stream and recoverable. +@@ -246,10 +252,7 @@ class HPackParser::Input { + // read prior to being able to get further in this parse. + void UnexpectedEOF(size_t min_progress_size) { + GPR_ASSERT(min_progress_size > 0); +- if (min_progress_size_ != 0 || error_.connection_error()) { +- GPR_DEBUG_ASSERT(eof_error()); +- return; +- } ++ if (eof_error()) return; + // Set min progress size, taking into account bytes parsed already but not + // consumed. + min_progress_size_ = min_progress_size + (begin_ - frontier_); +@@ -302,13 +305,18 @@ class HPackParser::Input { + // Do not use this directly, instead use SetErrorAndContinueParsing or + // SetErrorAndStopParsing. + void SetError(HpackParseResult error) { +- if (!error_.ok() || min_progress_size_ > 0) { +- if (error.connection_error() && !error_.connection_error()) { +- error_ = std::move(error); // connection errors dominate ++ SetErrorFor(frame_error_, error); ++ SetErrorFor(field_error_, std::move(error)); ++ } ++ ++ void SetErrorFor(HpackParseResult& error, HpackParseResult new_error) { ++ if (!error.ok() || min_progress_size_ > 0) { ++ if (new_error.connection_error() && !error.connection_error()) { ++ error = std::move(new_error); // connection errors dominate + } + return; + } +- error_ = std::move(error); ++ error = std::move(new_error); + } + + // Refcount if we are backed by a slice +@@ -320,7 +328,8 @@ class HPackParser::Input { + // Frontier denotes the first byte past successfully processed input + const uint8_t* frontier_; + // Current error +- HpackParseResult& error_; ++ HpackParseResult& frame_error_; ++ HpackParseResult& field_error_; + // If the error was EOF, we flag it here by noting how many more bytes would + // be needed to make progress + size_t min_progress_size_ = 0; +@@ -597,6 +606,7 @@ class HPackParser::Parser { + bool ParseTop() { + GPR_DEBUG_ASSERT(state_.parse_state == ParseState::kTop); + auto cur = *input_->Next(); ++ input_->ClearFieldError(); + switch (cur >> 4) { + // Literal header not indexed - First byte format: 0000xxxx + // Literal header never indexed - First byte format: 0001xxxx +@@ -702,7 +712,7 @@ class HPackParser::Parser { + break; + } + gpr_log( +- GPR_DEBUG, "HTTP:%d:%s:%s: %s%s", log_info_.stream_id, type, ++ GPR_INFO, "HTTP:%d:%s:%s: %s%s", log_info_.stream_id, type, + log_info_.is_client ? "CLI" : "SVR", memento.md.DebugString().c_str(), + memento.parse_status == nullptr + ? "" +@@ -951,11 +961,10 @@ class HPackParser::Parser { + state_.string_length) + : String::Parse(input_, state_.is_string_huff_compressed, + state_.string_length); +- HpackParseResult& status = state_.frame_error; + absl::string_view key_string; + if (auto* s = absl::get_if(&state_.key)) { + key_string = s->as_string_view(); +- if (status.ok()) { ++ if (state_.field_error.ok()) { + auto r = ValidateKey(key_string); + if (r != ValidateMetadataResult::kOk) { + input_->SetErrorAndContinueParsing( +@@ -965,7 +974,7 @@ class HPackParser::Parser { + } else { + const auto* memento = absl::get(state_.key); + key_string = memento->md.key(); +- if (status.ok() && memento->parse_status != nullptr) { ++ if (state_.field_error.ok() && memento->parse_status != nullptr) { + input_->SetErrorAndContinueParsing(*memento->parse_status); + } + } +@@ -992,16 +1001,16 @@ class HPackParser::Parser { + key_string.size() + value.wire_size + hpack_constants::kEntryOverhead; + auto md = grpc_metadata_batch::Parse( + key_string, std::move(value_slice), state_.add_to_table, transport_size, +- [key_string, &status, this](absl::string_view message, const Slice&) { +- if (!status.ok()) return; ++ [key_string, this](absl::string_view message, const Slice&) { ++ if (!state_.field_error.ok()) return; + input_->SetErrorAndContinueParsing( + HpackParseResult::MetadataParseError(key_string)); + gpr_log(GPR_ERROR, "Error parsing '%s' metadata: %s", + std::string(key_string).c_str(), + std::string(message).c_str()); + }); +- HPackTable::Memento memento{std::move(md), +- status.PersistentStreamErrorOrNullptr()}; ++ HPackTable::Memento memento{ ++ std::move(md), state_.field_error.PersistentStreamErrorOrNullptr()}; + input_->UpdateFrontier(); + state_.parse_state = ParseState::kTop; + if (state_.add_to_table) { +@@ -1163,13 +1172,13 @@ grpc_error_handle HPackParser::Parse( + std::vector buffer = std::move(unparsed_bytes_); + return ParseInput( + Input(nullptr, buffer.data(), buffer.data() + buffer.size(), bitsrc, +- state_.frame_error), ++ state_.frame_error, state_.field_error), + is_last, call_tracer); + } +- return ParseInput( +- Input(slice.refcount, GRPC_SLICE_START_PTR(slice), +- GRPC_SLICE_END_PTR(slice), bitsrc, state_.frame_error), +- is_last, call_tracer); ++ return ParseInput(Input(slice.refcount, GRPC_SLICE_START_PTR(slice), ++ GRPC_SLICE_END_PTR(slice), bitsrc, state_.frame_error, ++ state_.field_error), ++ is_last, call_tracer); + } + + grpc_error_handle HPackParser::ParseInput( +diff --git a/src/core/ext/transport/chttp2/transport/hpack_parser.h b/src/core/ext/transport/chttp2/transport/hpack_parser.h +index 37456683b6..55842e47eb 100644 +--- a/src/core/ext/transport/chttp2/transport/hpack_parser.h ++++ b/src/core/ext/transport/chttp2/transport/hpack_parser.h +@@ -236,6 +236,8 @@ class HPackParser { + HPackTable hpack_table; + // Error so far for this frame (set by class Input) + HpackParseResult frame_error; ++ // Error so far for this field (set by class Input) ++ HpackParseResult field_error; + // Length of frame so far. + uint32_t frame_length = 0; + // Length of the string being parsed +diff --git a/test/core/transport/chttp2/hpack_parser_test.cc b/test/core/transport/chttp2/hpack_parser_test.cc +index 3772d909b9..d5b9c6cb68 100644 +--- a/test/core/transport/chttp2/hpack_parser_test.cc ++++ b/test/core/transport/chttp2/hpack_parser_test.cc +@@ -440,19 +440,82 @@ INSTANTIATE_TEST_SUITE_P( + Test{"Base64LegalEncoding", + {}, + {}, +- {// Binary metadata: created using: +- // tools/codegen/core/gen_header_frame.py +- // --compression inc --no_framing --output hexstr +- // < test/core/transport/chttp2/bad-base64.headers +- {"4009612e622e632d62696e1c6c75636b696c7920666f722075732c206974" +- "27732074756573646179", +- absl::InternalError("Error parsing 'a.b.c-bin' metadata: " +- "illegal base64 encoding"), +- 0}, +- {"be", +- absl::InternalError("Error parsing 'a.b.c-bin' metadata: " +- "illegal base64 encoding"), +- 0}}}, ++ { ++ // Binary metadata: created using: ++ // tools/codegen/core/gen_header_frame.py ++ // --compression inc --no_framing --output hexstr ++ // < test/core/transport/chttp2/bad-base64.headers ++ {"4009612e622e632d62696e1c6c75636b696c7920666f722075732c206974" ++ "27732074756573646179", ++ absl::InternalError("Error parsing 'a.b.c-bin' metadata: " ++ "illegal base64 encoding"), ++ 0}, ++ {"be", ++ absl::InternalError("Error parsing 'a.b.c-bin' metadata: " ++ "illegal base64 encoding"), ++ kEndOfHeaders}, ++ {"82", ":method: GET\n", 0}, ++ }}, ++ Test{"Base64LegalEncodingWorksAfterFailure", ++ {}, ++ {}, ++ { ++ // Binary metadata: created using: ++ // tools/codegen/core/gen_header_frame.py ++ // --compression inc --no_framing --output hexstr ++ // < test/core/transport/chttp2/bad-base64.headers ++ {"4009612e622e632d62696e1c6c75636b696c7920666f722075732c206974" ++ "27732074756573646179", ++ absl::InternalError("Error parsing 'a.b.c-bin' metadata: " ++ "illegal base64 encoding"), ++ 0}, ++ {"be", ++ absl::InternalError("Error parsing 'a.b.c-bin' metadata: " ++ "illegal base64 encoding"), ++ 0}, ++ {"400e636f6e74656e742d6c656e6774680135", ++ absl::InternalError("Error parsing 'a.b.c-bin' metadata: " ++ "illegal base64 encoding"), ++ kEndOfHeaders}, ++ {"be", "content-length: 5\n", 0}, ++ }}, ++ Test{"Base64LegalEncodingWorksAfterFailure2", ++ {}, ++ {}, ++ { ++ {// Generated with: tools/codegen/core/gen_header_frame.py ++ // --compression inc --output hexstr --no_framing < ++ // test/core/transport/chttp2/MiXeD-CaSe.headers ++ "400a4d695865442d436153651073686f756c64206e6f74207061727365", ++ absl::InternalError("Illegal header key: MiXeD-CaSe"), 0}, ++ // Binary metadata: created using: ++ // tools/codegen/core/gen_header_frame.py ++ // --compression inc --no_framing --output hexstr ++ // < test/core/transport/chttp2/bad-base64.headers ++ {"4009612e622e632d62696e1c6c75636b696c7920666f722075732c206974" ++ "27732074756573646179", ++ absl::InternalError("Illegal header key: MiXeD-CaSe"), 0}, ++ {"be", absl::InternalError("Illegal header key: MiXeD-CaSe"), ++ 0}, ++ {"400e636f6e74656e742d6c656e6774680135", ++ absl::InternalError("Illegal header key: MiXeD-CaSe"), ++ kEndOfHeaders}, ++ {"be", "content-length: 5\n", 0}, ++ {"bf", ++ absl::InternalError("Error parsing 'a.b.c-bin' metadata: " ++ "illegal base64 encoding"), ++ 0}, ++ // Only the first error in each frame is reported, so we should ++ // still see the same error here... ++ {"c0", ++ absl::InternalError("Error parsing 'a.b.c-bin' metadata: " ++ "illegal base64 encoding"), ++ kEndOfHeaders}, ++ // ... but if we look at the next frame we should see the ++ // stored error ++ {"c0", absl::InternalError("Illegal header key: MiXeD-CaSe"), ++ kEndOfHeaders}, ++ }}, + Test{"TeIsTrailers", + {}, + {}, +diff --git a/test/core/transport/chttp2/hpack_sync_fuzzer.cc b/test/core/transport/chttp2/hpack_sync_fuzzer.cc +index 47e426547a..9afa41fa6d 100644 +--- a/test/core/transport/chttp2/hpack_sync_fuzzer.cc ++++ b/test/core/transport/chttp2/hpack_sync_fuzzer.cc +@@ -85,6 +85,10 @@ void FuzzOneInput(const hpack_sync_fuzzer::Msg& msg) { + // Not an interesting case to fuzz + continue; + } ++ if (msg.check_ab_preservation() && ++ header.literal_inc_idx().key() == "a") { ++ continue; ++ } + if (absl::EndsWith(header.literal_inc_idx().value(), "-bin")) { + std::ignore = encoder.EmitLitHdrWithBinaryStringKeyIncIdx( + Slice::FromCopiedString(header.literal_inc_idx().key()), +@@ -96,6 +100,10 @@ void FuzzOneInput(const hpack_sync_fuzzer::Msg& msg) { + } + break; + case hpack_sync_fuzzer::Header::kLiteralNotIdx: ++ if (msg.check_ab_preservation() && ++ header.literal_not_idx().key() == "a") { ++ continue; ++ } + if (absl::EndsWith(header.literal_not_idx().value(), "-bin")) { + encoder.EmitLitHdrWithBinaryStringKeyNotIdx( + Slice::FromCopiedString(header.literal_not_idx().key()), +@@ -114,6 +122,10 @@ void FuzzOneInput(const hpack_sync_fuzzer::Msg& msg) { + break; + } + } ++ if (msg.check_ab_preservation()) { ++ std::ignore = encoder.EmitLitHdrWithNonBinaryStringKeyIncIdx( ++ Slice::FromCopiedString("a"), Slice::FromCopiedString("b")); ++ } + + // STAGE 2: Decode the buffer (encode_output) into a list of headers + HPackParser parser; +@@ -140,6 +152,21 @@ void FuzzOneInput(const hpack_sync_fuzzer::Msg& msg) { + } + } + ++ if (seen_errors.empty() && msg.check_ab_preservation()) { ++ std::string backing; ++ auto a_value = read_metadata.GetStringValue("a", &backing); ++ if (!a_value.has_value()) { ++ fprintf(stderr, "Expected 'a' header to be present: %s\n", ++ read_metadata.DebugString().c_str()); ++ abort(); ++ } ++ if (a_value != "b") { ++ fprintf(stderr, "Expected 'a' header to be 'b', got '%s'\n", ++ std::string(*a_value).c_str()); ++ abort(); ++ } ++ } ++ + // STAGE 3: If we reached here we either had a stream error or no error + // parsing. + // Either way, the hpack tables should be of the same size between client and +@@ -168,6 +195,41 @@ void FuzzOneInput(const hpack_sync_fuzzer::Msg& msg) { + } + abort(); + } ++ ++ if (msg.check_ab_preservation()) { ++ SliceBuffer encode_output_2; ++ hpack_encoder_detail::Encoder encoder_2( ++ &compressor, msg.use_true_binary_metadata(), encode_output_2); ++ encoder_2.EmitIndexed(62); ++ GPR_ASSERT(encode_output_2.Count() == 1); ++ grpc_metadata_batch read_metadata_2(arena.get()); ++ parser.BeginFrame( ++ &read_metadata_2, 1024, 1024, HPackParser::Boundary::EndOfHeaders, ++ HPackParser::Priority::None, ++ HPackParser::LogInfo{3, HPackParser::LogInfo::kHeaders, false}); ++ auto err = parser.Parse(encode_output_2.c_slice_at(0), true, ++ absl::BitGenRef(proto_bit_src), ++ /*call_tracer=*/nullptr); ++ if (!err.ok()) { ++ fprintf(stderr, "Error parsing preservation encoded data: %s\n", ++ err.ToString().c_str()); ++ abort(); ++ } ++ std::string backing; ++ auto a_value = read_metadata_2.GetStringValue("a", &backing); ++ if (!a_value.has_value()) { ++ fprintf(stderr, ++ "Expected 'a' header to be present: %s\nfirst metadata: %s\n", ++ read_metadata_2.DebugString().c_str(), ++ read_metadata.DebugString().c_str()); ++ abort(); ++ } ++ if (a_value != "b") { ++ fprintf(stderr, "Expected 'a' header to be 'b', got '%s'\n", ++ std::string(*a_value).c_str()); ++ abort(); ++ } ++ } + } + + } // namespace +diff --git a/test/core/transport/chttp2/hpack_sync_fuzzer.proto b/test/core/transport/chttp2/hpack_sync_fuzzer.proto +index 72792b60d6..2c075a6abb 100644 +--- a/test/core/transport/chttp2/hpack_sync_fuzzer.proto ++++ b/test/core/transport/chttp2/hpack_sync_fuzzer.proto +@@ -44,4 +44,7 @@ message Msg { + repeated Header headers = 2; + grpc.testing.FuzzConfigVars config_vars = 3; + repeated uint64 random_numbers = 4; ++ // Ensure that a header "a: b" appended to headers with hpack incremental ++ // indexing is correctly added to the hpack table. ++ bool check_ab_preservation = 5; + } +-- +2.33.0 + diff --git a/backport-Ignore-Connection-Aborted-errors-on-accept-29318.patch b/backport-Ignore-Connection-Aborted-errors-on-accept-29318.patch deleted file mode 100644 index b3f9e5d18d226de69980c57a729d0d19c6ad976e..0000000000000000000000000000000000000000 --- a/backport-Ignore-Connection-Aborted-errors-on-accept-29318.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 5850cba2957cc894477e735a74aa6c246b499ff4 Mon Sep 17 00:00:00 2001 -From: Yash Tibrewal -Date: Mon, 11 Apr 2022 15:49:18 -0700 -Subject: [PATCH] Ignore Connection Aborted errors on accept (#29318) - -* Ignore Connection Aborted errors on accept - -* Reviewer comments ---- - src/core/lib/iomgr/tcp_server_posix.cc | 32 +++++++++++++------------- - 1 file changed, 16 insertions(+), 16 deletions(-) - -diff --git a/src/core/lib/iomgr/tcp_server_posix.cc b/src/core/lib/iomgr/tcp_server_posix.cc -index c40ddbf646..f02bb8396a 100644 ---- a/src/core/lib/iomgr/tcp_server_posix.cc -+++ b/src/core/lib/iomgr/tcp_server_posix.cc -@@ -204,22 +204,22 @@ static void on_read(void* arg, grpc_error_handle err) { - strip off the ::ffff:0.0.0.0/96 prefix first. */ - int fd = grpc_accept4(sp->fd, &addr, 1, 1); - if (fd < 0) { -- switch (errno) { -- case EINTR: -- continue; -- case EAGAIN: -- grpc_fd_notify_on_read(sp->emfd, &sp->read_closure); -- return; -- default: -- gpr_mu_lock(&sp->server->mu); -- if (!sp->server->shutdown_listeners) { -- gpr_log(GPR_ERROR, "Failed accept4: %s", strerror(errno)); -- } else { -- /* if we have shutdown listeners, accept4 could fail, and we -- needn't notify users */ -- } -- gpr_mu_unlock(&sp->server->mu); -- goto error; -+ if (errno == EINTR) { -+ continue; -+ } else if (errno == EAGAIN || errno == ECONNABORTED || -+ errno == EWOULDBLOCK) { -+ grpc_fd_notify_on_read(sp->emfd, &sp->read_closure); -+ return; -+ } else { -+ gpr_mu_lock(&sp->server->mu); -+ if (!sp->server->shutdown_listeners) { -+ gpr_log(GPR_ERROR, "Failed accept4: %s", strerror(errno)); -+ } else { -+ /* if we have shutdown listeners, accept4 could fail, and we -+ needn't notify users */ -+ } -+ gpr_mu_unlock(&sp->server->mu); -+ goto error; - } - } - --- -2.33.0 - diff --git a/backport-grpc-1.41.1-python-grpcio-use-system-abseil.patch b/backport-grpc-1.41.1-python-grpcio-use-system-abseil.patch deleted file mode 100644 index 9d406aa368655e38d8d2e1fd0329e67a09173e4f..0000000000000000000000000000000000000000 --- a/backport-grpc-1.41.1-python-grpcio-use-system-abseil.patch +++ /dev/null @@ -1,46 +0,0 @@ -diff -Naur grpc-1.40.0-original/setup.py grpc-1.40.0/setup.py ---- grpc-1.40.0-original/setup.py 2021-09-03 19:20:52.000000000 -0400 -+++ grpc-1.40.0/setup.py 2021-09-07 14:57:55.247990450 -0400 -@@ -29,6 +29,7 @@ - from distutils import util - import os - import os.path -+import pathlib - import platform - import re - import shlex -@@ -154,6 +155,11 @@ - # runtime, the shared library must be installed - BUILD_WITH_SYSTEM_RE2 = _env_bool_value('GRPC_PYTHON_BUILD_SYSTEM_RE2', 'False') - -+# Export this variable to use the system installation of abseil. You need to -+# have the header files installed (in /usr/include/absl) and during -+# runtime, the shared library must be installed -+BUILD_WITH_SYSTEM_ABSL = os.environ.get('GRPC_PYTHON_BUILD_SYSTEM_ABSL', False) -+ - # Export this variable to force building the python extension with a statically linked libstdc++. - # At least on linux, this is normally not needed as we can build manylinux-compatible wheels on linux just fine - # without statically linking libstdc++ (which leads to a slight increase in the wheel size). -@@ -296,6 +302,10 @@ - CORE_C_FILES = filter(lambda x: 'third_party/re2' not in x, CORE_C_FILES) - RE2_INCLUDE = (os.path.join('/usr', 'include', 're2'),) - -+if BUILD_WITH_SYSTEM_ABSL: -+ CORE_C_FILES = filter(lambda x: 'third_party/abseil-cpp' not in x, CORE_C_FILES) -+ ABSL_INCLUDE = (os.path.join('/usr', 'include'),) -+ - EXTENSION_INCLUDE_DIRECTORIES = ((PYTHON_STEM,) + CORE_INCLUDE + ABSL_INCLUDE + - ADDRESS_SORTING_INCLUDE + CARES_INCLUDE + - RE2_INCLUDE + SSL_INCLUDE + UPB_INCLUDE + -@@ -325,6 +335,10 @@ - EXTENSION_LIBRARIES += ('cares',) - if BUILD_WITH_SYSTEM_RE2: - EXTENSION_LIBRARIES += ('re2',) -+if BUILD_WITH_SYSTEM_ABSL: -+ EXTENSION_LIBRARIES += tuple( -+ lib.stem[3:] for lib in pathlib.Path('/usr').glob('lib*/libabsl_*.so') -+ ) - - DEFINE_MACROS = (('_WIN32_WINNT', 0x600),) - asm_files = [] - diff --git a/backport-iomgr-EventEngine-Improve-server-handling-o.patch b/backport-iomgr-EventEngine-Improve-server-handling-o.patch deleted file mode 100644 index 95e8d4ae07fbdad540ac6244f02e843fceafdd41..0000000000000000000000000000000000000000 --- a/backport-iomgr-EventEngine-Improve-server-handling-o.patch +++ /dev/null @@ -1,192 +0,0 @@ -From 1e86ca5834b94cae7d5e6d219056c0fc895cf95d Mon Sep 17 00:00:00 2001 -From: AJ Heller -Date: Wed, 12 Jul 2023 18:42:09 -0700 -Subject: [PATCH] [backport][iomgr][EventEngine] Improve server handling of - file descriptor exhaustion (#33672) - -Backport of #33656 ---- - src/core/lib/iomgr/tcp_server_posix.cc | 46 ++++++++++++++----- - src/core/lib/iomgr/tcp_server_utils_posix.h | 13 +++++ - .../iomgr/tcp_server_utils_posix_common.cc | 21 ++++++++ - 3 files changed, 67 insertions(+), 13 deletions(-) - -diff --git a/src/core/lib/iomgr/tcp_server_posix.cc b/src/core/lib/iomgr/tcp_server_posix.cc -index a1db16d916..6804928fe3 100644 ---- a/src/core/lib/iomgr/tcp_server_posix.cc -+++ b/src/core/lib/iomgr/tcp_server_posix.cc -@@ -16,13 +16,17 @@ - * - */ - -+#include -+ -+#include -+ -+#include -+ - /* FIXME: "posix" files shouldn't be depending on _GNU_SOURCE */ - #ifndef _GNU_SOURCE - #define _GNU_SOURCE - #endif - --#include -- - #include "src/core/lib/iomgr/port.h" - - #ifdef GRPC_POSIX_SOCKET_TCP_SERVER -@@ -45,6 +49,7 @@ - #include "absl/strings/str_cat.h" - #include "absl/strings/str_format.h" - -+#include - #include - #include - #include -@@ -350,21 +357,35 @@ static void on_read(void* arg, grpc_error_handle err) { - if (fd < 0) { - if (errno == EINTR) { - continue; -- } else if (errno == EAGAIN || errno == ECONNABORTED || -- errno == EWOULDBLOCK) { -+ } -+ // When the process runs out of fds, accept4() returns EMFILE. When this -+ // happens, the connection is left in the accept queue until either a -+ // read event triggers the on_read callback, or time has passed and the -+ // accept should be re-tried regardless. This callback is not cancelled, -+ // so a spurious wakeup may occur even when there's nothing to accept. -+ // This is not a performant code path, but if an fd limit has been -+ // reached, the system is likely in an unhappy state regardless. -+ if (errno == EMFILE) { -+ grpc_fd_notify_on_read(sp->emfd, &sp->read_closure); -+ if (gpr_atm_full_xchg(&sp->retry_timer_armed, true)) return; -+ grpc_timer_init(&sp->retry_timer, -+ grpc_core::ExecCtx::Get()->Now() + 1 * GPR_MS_PER_SEC, -+ &sp->retry_closure); -+ return; -+ } -+ if (errno == EAGAIN || errno == ECONNABORTED || errno == EWOULDBLOCK) { - grpc_fd_notify_on_read(sp->emfd, &sp->read_closure); - return; -+ } -+ gpr_mu_lock(&sp->server->mu); -+ if (!sp->server->shutdown_listeners) { -+ gpr_log(GPR_ERROR, "Failed accept4: %s", strerror(errno)); - } else { -- gpr_mu_lock(&sp->server->mu); -- if (!sp->server->shutdown_listeners) { -- gpr_log(GPR_ERROR, "Failed accept4: %s", strerror(errno)); -- } else { -- /* if we have shutdown listeners, accept4 could fail, and we -- needn't notify users */ -- } -- gpr_mu_unlock(&sp->server->mu); -- goto error; -+ // if we have shutdown listeners, accept4 could fail, and we -+ // needn't notify users - } -+ gpr_mu_unlock(&sp->server->mu); -+ goto error; - } - - /* For UNIX sockets, the accept call might not fill up the member sun_path -@@ -558,6 +581,7 @@ static grpc_error_handle clone_port(grpc_tcp_listener* listener, - sp->port_index = listener->port_index; - sp->fd_index = listener->fd_index + count - i; - GPR_ASSERT(sp->emfd); -+ grpc_tcp_server_listener_initialize_retry_timer(sp); - while (listener->server->tail->next != nullptr) { - listener->server->tail = listener->server->tail->next; - } -@@ -791,6 +815,7 @@ static void tcp_server_shutdown_listeners(grpc_tcp_server* s) { - if (s->active_ports) { - grpc_tcp_listener* sp; - for (sp = s->head; sp; sp = sp->next) { -+ grpc_timer_cancel(&sp->retry_timer); - grpc_fd_shutdown(sp->emfd, - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Server shutdown")); - } -diff --git a/src/core/lib/iomgr/tcp_server_utils_posix.h b/src/core/lib/iomgr/tcp_server_utils_posix.h -index 26cef0209f..de5a888cff 100644 ---- a/src/core/lib/iomgr/tcp_server_utils_posix.h -+++ b/src/core/lib/iomgr/tcp_server_utils_posix.h -@@ -30,6 +30,7 @@ - #include "src/core/lib/iomgr/resolve_address.h" - #include "src/core/lib/iomgr/socket_utils_posix.h" - #include "src/core/lib/iomgr/tcp_server.h" -+#include "src/core/lib/iomgr/timer.h" - - /* one listening port */ - typedef struct grpc_tcp_listener { -@@ -52,6 +53,11 @@ typedef struct grpc_tcp_listener { - identified while iterating through 'next'. */ - struct grpc_tcp_listener* sibling; - int is_sibling; -+ // If an accept4() call fails, a timer is started to drain the accept queue in -+ // case no further connection attempts reach the gRPC server. -+ grpc_closure retry_closure; -+ grpc_timer retry_timer; -+ gpr_atm retry_timer_armed; - } grpc_tcp_listener; - - /* the overall server */ -@@ -139,4 +145,10 @@ grpc_error_handle grpc_tcp_server_prepare_socket( - /* Ruturn true if the platform supports ifaddrs */ - bool grpc_tcp_server_have_ifaddrs(void); - -+// Initialize (but don't start) the timer and callback to retry accept4() on a -+// listening socket after file descriptors have been exhausted. This must be -+// called when creating a new listener. -+void grpc_tcp_server_listener_initialize_retry_timer( -+ grpc_tcp_listener* listener); -+ - #endif /* GRPC_CORE_LIB_IOMGR_TCP_SERVER_UTILS_POSIX_H */ -diff --git a/src/core/lib/iomgr/tcp_server_utils_posix_common.cc b/src/core/lib/iomgr/tcp_server_utils_posix_common.cc -index 574fd02d0d..a32f542c4a 100644 ---- a/src/core/lib/iomgr/tcp_server_utils_posix_common.cc -+++ b/src/core/lib/iomgr/tcp_server_utils_posix_common.cc -@@ -18,6 +18,8 @@ - - #include - -+#include -+ - #include "src/core/lib/iomgr/port.h" - - #ifdef GRPC_POSIX_SOCKET_TCP_SERVER_UTILS_COMMON -@@ -81,6 +83,24 @@ static int get_max_accept_queue_size(void) { - return s_max_accept_queue_size; - } - -+static void listener_retry_timer_cb(void* arg, grpc_error_handle err) { -+ // Do nothing if cancelled. -+ if (err != GRPC_ERROR_NONE) return; -+ grpc_tcp_listener* listener = static_cast(arg); -+ gpr_atm_no_barrier_store(&listener->retry_timer_armed, false); -+ if (!grpc_fd_is_shutdown(listener->emfd)) { -+ grpc_fd_set_readable(listener->emfd); -+ } -+} -+ -+void grpc_tcp_server_listener_initialize_retry_timer( -+ grpc_tcp_listener* listener) { -+ gpr_atm_no_barrier_store(&listener->retry_timer_armed, false); -+ grpc_timer_init_unset(&listener->retry_timer); -+ GRPC_CLOSURE_INIT(&listener->retry_closure, listener_retry_timer_cb, listener, -+ grpc_schedule_on_exec_ctx); -+} -+ - static grpc_error_handle add_socket_to_server(grpc_tcp_server* s, int fd, - const grpc_resolved_address* addr, - unsigned port_index, -@@ -112,6 +132,7 @@ static grpc_error_handle add_socket_to_server(grpc_tcp_server* s, int fd, - sp->server = s; - sp->fd = fd; - sp->emfd = grpc_fd_create(fd, name.c_str(), true); -+ grpc_tcp_server_listener_initialize_retry_timer(sp); - memcpy(&sp->addr, addr, sizeof(grpc_resolved_address)); - sp->port = port; - sp->port_index = port_index; --- -2.33.0 - diff --git a/fix-CVE-2023-33953-add-header-limit.patch b/fix-CVE-2023-33953-add-header-limit.patch deleted file mode 100644 index 62275896c337980acdea3aafbf7a9b7dddb8f318..0000000000000000000000000000000000000000 --- a/fix-CVE-2023-33953-add-header-limit.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 5fe782778f535ae68508fb7979df1cbfbdf4d6de Mon Sep 17 00:00:00 2001 -From: sunsuwan -Date: Mon, 4 Sep 2023 21:45:49 +0800 -Subject: [PATCH] CVE-2023-33953 add header limit - -Signed-off-by: zhouyihang -Signed-off-by: sunsuwan ---- - .../ext/transport/chttp2/transport/hpack_parser.cc | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - -diff --git a/src/core/ext/transport/chttp2/transport/hpack_parser.cc b/src/core/ext/transport/chttp2/transport/hpack_parser.cc -index 09681fa..6b191a7 100644 ---- a/src/core/ext/transport/chttp2/transport/hpack_parser.cc -+++ b/src/core/ext/transport/chttp2/transport/hpack_parser.cc -@@ -1372,6 +1372,18 @@ grpc_error_handle grpc_chttp2_header_parser_parse(void* hpack_parser, - auto* parser = static_cast(hpack_parser); - if (s != nullptr) { - s->stats.incoming.header_bytes += GRPC_SLICE_LENGTH(slice); -+ if (s->stats.incoming.header_bytes > t->settings[GRPC_ACKED_SETTINGS] -+ [GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE]) { -+ grpc_chttp2_cancel_stream( -+ t, s, -+ grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING( -+ "received header size exceeds limit"), -+ GRPC_ERROR_INT_GRPC_STATUS, -+ GRPC_STATUS_RESOURCE_EXHAUSTED)); -+ grpc_chttp2_parsing_become_skip_parser(t); -+ s->seen_error = true; -+ return GRPC_ERROR_NONE; -+ } - } - grpc_error_handle error = parser->Parse(slice, is_last != 0); - if (error != GRPC_ERROR_NONE) { --- -2.33.0 - diff --git a/grpc-1.41.1.tar.gz b/grpc-1.60.0.tar.gz similarity index 37% rename from grpc-1.41.1.tar.gz rename to grpc-1.60.0.tar.gz index f7fe9a2de0ecd6b1f152212dc36ddaeb6f0fc01e..74a6b666ecb4f895d49b8e8470bca2434d0aac72 100644 Binary files a/grpc-1.41.1.tar.gz and b/grpc-1.60.0.tar.gz differ diff --git a/grpc.spec b/grpc.spec index f2bb3a0b16ae0a39a1883d5b91bf6f22f71af90d..e20877eaa859b8a53f3a6544bac4bbd6bb8eaf43 100644 --- a/grpc.spec +++ b/grpc.spec @@ -1,9 +1,10 @@ -%global c_so_version 19 -%global cpp_so_version 1.41 +%global c_so_version 37 +%global cpp_so_version 1.60 +%global cpp_std 17 Name: grpc -Version: 1.41.1 -Release: 8 +Version: 1.60.0 +Release: 1 Summary: A modern, open source high performance RPC framework that can run in any environment License: ASL 2.0 URL: https://www.grpc.io @@ -11,14 +12,12 @@ Source0: https://github.com/grpc/grpc/archive/v%{version}/%{name}-%{versio Patch0006: repair-pkgconfig-path.patch Patch0007: add-secure-compile-option-in-Makefile.patch -Patch0010: backport-grpc-1.41.1-python-grpcio-use-system-abseil.patch -Patch0011: backport-Ignore-Connection-Aborted-errors-on-accept-29318.patch -Patch0012: backport-iomgr-EventEngine-Improve-server-handling-o.patch -Patch0013: fix-CVE-2023-33953-add-header-limit.patch -Patch0014: remove-cert-expired-on-20230930.patch -Patch0015: remove-cert-expired-at-20250512.patch - -BuildRequires: gcc-c++ pkgconfig protobuf-devel protobuf-compiler +Patch0008: remove-cert-expired-on-20230930.patch +Patch0009: remove-cert-expired-at-20250512.patch +Patch0010: backport-CVE-2024-7246-chttp2-Fix-a-bug-in-hpack-error-handling.patch +Patch0011: backport-CVE-2024-11407.patch + +BuildRequires: gcc-c++ pkgconfig protobuf-devel protobuf-compiler protobuf-lite-devel BuildRequires: openssl-devel c-ares-devel gtest-devel zlib-devel gperftools-devel BuildRequires: python3-devel python3-setuptools python3-Cython BuildRequires: cmake >= 3.13.0 @@ -63,11 +62,20 @@ Python3 bindings for gRPC. sed -i 's:^prefix ?= .*:prefix ?= %{_prefix}:' Makefile sed -i 's:$(prefix)/lib:$(prefix)/%{_lib}:' Makefile sed -i 's:^GTEST_LIB =.*::' Makefile +#avoid downloading +mkdir %{_builddir}/%{name}-%{version}/third_party/opencensus-proto/src +sed -r -i 's/(std=c\+\+)14/\1%{cpp_std}/g' \ + setup.py grpc.gyp Rakefile \ + examples/cpp/*/Makefile \ + examples/cpp/*/CMakeLists.txt \ + tools/run_tests/artifacts/artifact_targets.py \ + tools/distrib/python/grpcio_tools/setup.py %build mkdir -p cmake/build cd cmake/build cmake ../../ -DgRPC_INSTALL=ON\ + -DCMAKE_CXX_STANDARD:STRING=%{cpp_std} \ -DgRPC_CARES_PROVIDER=package \ -DgRPC_PROTOBUF_PROVIDER=package \ -DgRPC_SSL_PROVIDER=package \ @@ -82,7 +90,9 @@ cmake ../../ -DgRPC_INSTALL=ON\ -DgRPC_INSTALL_PKGCONFIGDIR=%{buildroot}%{_libdir}/pkgconfig \ -DCMAKE_INSTALL_PREFIX=%{_prefix} \ -DBUILD_SHARED_LIBS=ON \ - -DCMAKE_VERBOSE_MAKEFILE=ON + -DCMAKE_VERBOSE_MAKEFILE=ON \ + -DCMAKE_EXE_LINKER_FLAGS=-Wl,--as-needed \ + -DCMAKE_SHARED_LINKER_FLAGS=-Wl,--as-needed make -j24 V=1 # build python module @@ -125,6 +135,11 @@ cd ../.. %{_libdir}/libgrpc++_unsecure.so.%{cpp_so_version}* %{_libdir}/libgrpc_plugin_support.so.%{cpp_so_version}* %{_libdir}/libgrpcpp_channelz.so.%{cpp_so_version}* +%{_libdir}/libgrpc_authorization_provider.so.%{cpp_so_version}* +%{_libdir}/libupb_collections_lib.so.%{c_so_version}* +%{_libdir}/libupb_json_lib.so.%{c_so_version}* +%{_libdir}/libupb_textformat_lib.so.%{c_so_version}* +%{_libdir}/libutf8_range_lib.so.%{c_so_version}* %files plugins %{_bindir}/grpc_*_plugin @@ -140,9 +155,15 @@ cd ../.. %files -n python3-grpcio %defattr(-,root,root) %{python3_sitearch}/grpc -%{python3_sitearch}/grpcio-%{version}-py?.?.egg-info +%{python3_sitearch}/grpcio-%{version}-py* %changelog +* Mon Apr 07 2025 xinghe - 1.60.0-1 +- Type:requirement +- CVE:NA +- SUG:NA +- DESC:update version to 1.60.0 + * Fri Jun 21 2024 zhouyihang - 1.41.1-8 - Type:bugfix - ID:NA diff --git a/repair-pkgconfig-path.patch b/repair-pkgconfig-path.patch index 69056415552eb71d11112cbb4dbbfae79da5fca1..01550253d396ece801add5c7f0c7f5b460fa672e 100644 --- a/repair-pkgconfig-path.patch +++ b/repair-pkgconfig-path.patch @@ -6,8 +6,9 @@ diff -urN grpc/cmake/pkg-config-template.pc.in grpc_new/cmake/pkg-config-templat @@ -1,7 +1,7 @@ prefix=@CMAKE_INSTALL_PREFIX@ exec_prefix=${prefix} - includedir=${prefix}/include --libdir=${exec_prefix}/lib +-includedir=${prefix}/@gRPC_INSTALL_INCLUDEDIR@ ++includedir=${prefix}/include +-libdir=${exec_prefix}/@gRPC_INSTALL_LIBDIR@ +libdir=${exec_prefix}/lib64 Name: @PC_NAME@ @@ -16,9 +17,9 @@ diff -urN grpc/CMakeLists.txt grpc_new/CMakeLists.txt --- grpc/CMakeLists.txt 2020-08-24 09:14:14.361862041 +0800 +++ grpc_new/CMakeLists.txt 2020-08-27 14:50:00.371507303 +0800 @@ -42,6 +42,7 @@ - set(gRPC_INSTALL_INCLUDEDIR "include" CACHE STRING "Installation directory for headers") set(gRPC_INSTALL_CMAKEDIR "lib/cmake/${PACKAGE_NAME}" CACHE STRING "Installation directory for cmake config files") set(gRPC_INSTALL_SHAREDIR "share/grpc" CACHE STRING "Installation directory for root certificates") + set(gRPC_BUILD_MSVC_MP_COUNT 0 CACHE STRING "The maximum number of processes for MSVC /MP option") +set(gRPC_INSTALL_PKGCONFIGDIR "lib/pkgconfig" CACHE STRING "Installation directory for pkgconfig") # Options @@ -27,7 +28,7 @@ diff -urN grpc/CMakeLists.txt grpc_new/CMakeLists.txt "${output_filepath}" @ONLY) install(FILES "${output_filepath}" -- DESTINATION "lib/pkgconfig/") +- DESTINATION "${gRPC_INSTALL_LIBDIR}/pkgconfig") + DESTINATION ${gRPC_INSTALL_PKGCONFIGDIR}) endfunction()