diff options
author | Libo Chen <libo.chen.cn@windriver.com> | 2024-12-06 12:00:41 +0800 |
---|---|---|
committer | Armin Kuster <akuster808@gmail.com> | 2024-12-15 14:05:17 -0500 |
commit | 85d783a457573878fdda93911f519cfb01cfcda3 (patch) | |
tree | 2cc5d7a7338aff102b544f0ce72e62468a097be2 | |
parent | 2ee358a0654f745bf2c85f436ffd6d925b8a2cf2 (diff) | |
download | meta-openembedded-85d783a457573878fdda93911f519cfb01cfcda3.tar.gz |
grpc: Fix CVE-2024-7246
Backport patches [1] to fix CVE-2024-7246.
[1] https://github.com/grpc/grpc/pull/37361/files
Signed-off-by: Libo Chen <libo.chen.cn@windriver.com>
Signed-off-by: Armin Kuster <akuster808@gmail.com>
-rw-r--r-- | meta-oe/recipes-devtools/grpc/grpc/CVE-2024-7246.patch | 420 | ||||
-rw-r--r-- | meta-oe/recipes-devtools/grpc/grpc_1.60.1.bb | 1 |
2 files changed, 421 insertions, 0 deletions
diff --git a/meta-oe/recipes-devtools/grpc/grpc/CVE-2024-7246.patch b/meta-oe/recipes-devtools/grpc/grpc/CVE-2024-7246.patch new file mode 100644 index 0000000000..a690b49c67 --- /dev/null +++ b/meta-oe/recipes-devtools/grpc/grpc/CVE-2024-7246.patch | |||
@@ -0,0 +1,420 @@ | |||
1 | From ac0948e39eb19c3325a576e152709d4cc915a7e4 Mon Sep 17 00:00:00 2001 | ||
2 | From: Craig Tiller <ctiller@google.com> | ||
3 | Date: Thu, 1 Aug 2024 13:02:27 -0700 | ||
4 | Subject: [PATCH] [v1.60] [chttp2] Fix a bug in hpack error handling (#37361) | ||
5 | |||
6 | PiperOrigin-RevId: 657234128 | ||
7 | PiperOrigin-RevId: 658458047 | ||
8 | |||
9 | Craig Tiller <ctiller@google.com> | ||
10 | |||
11 | CVE: CVE-2024-7246 | ||
12 | |||
13 | Upstream-Status: Backport | ||
14 | [https://github.com/grpc/grpc/pull/37361/files] | ||
15 | |||
16 | Signed-off-by: Libo Chen <libo.chen.cn@windriver.com> | ||
17 | --- | ||
18 | .../chttp2/transport/hpack_parser.cc | 63 +++++++------ | ||
19 | .../transport/chttp2/transport/hpack_parser.h | 2 + | ||
20 | .../transport/chttp2/hpack_parser_test.cc | 89 ++++++++++++++++--- | ||
21 | .../transport/chttp2/hpack_sync_fuzzer.cc | 62 +++++++++++++ | ||
22 | .../transport/chttp2/hpack_sync_fuzzer.proto | 3 + | ||
23 | 5 files changed, 179 insertions(+), 40 deletions(-) | ||
24 | |||
25 | diff --git a/src/core/ext/transport/chttp2/transport/hpack_parser.cc b/src/core/ext/transport/chttp2/transport/hpack_parser.cc | ||
26 | index 31bf464..f2fe80c 100644 | ||
27 | --- a/src/core/ext/transport/chttp2/transport/hpack_parser.cc | ||
28 | +++ b/src/core/ext/transport/chttp2/transport/hpack_parser.cc | ||
29 | @@ -91,12 +91,14 @@ constexpr Base64InverseTable kBase64InverseTable; | ||
30 | class HPackParser::Input { | ||
31 | public: | ||
32 | Input(grpc_slice_refcount* current_slice_refcount, const uint8_t* begin, | ||
33 | - const uint8_t* end, absl::BitGenRef bitsrc, HpackParseResult& error) | ||
34 | + const uint8_t* end, absl::BitGenRef bitsrc, | ||
35 | + HpackParseResult& frame_error, HpackParseResult& field_error) | ||
36 | : current_slice_refcount_(current_slice_refcount), | ||
37 | begin_(begin), | ||
38 | end_(end), | ||
39 | frontier_(begin), | ||
40 | - error_(error), | ||
41 | + frame_error_(frame_error), | ||
42 | + field_error_(field_error), | ||
43 | bitsrc_(bitsrc) {} | ||
44 | |||
45 | // If input is backed by a slice, retrieve its refcount. If not, return | ||
46 | @@ -215,14 +217,18 @@ class HPackParser::Input { | ||
47 | |||
48 | // Check if we saw an EOF | ||
49 | bool eof_error() const { | ||
50 | - return min_progress_size_ != 0 || error_.connection_error(); | ||
51 | + return min_progress_size_ != 0 || frame_error_.connection_error(); | ||
52 | + } | ||
53 | + | ||
54 | + // Reset the field error to be ok | ||
55 | + void ClearFieldError() { | ||
56 | + if (field_error_.ok()) return; | ||
57 | + field_error_ = HpackParseResult(); | ||
58 | } | ||
59 | |||
60 | // Minimum number of bytes to unstuck the current parse | ||
61 | size_t min_progress_size() const { return min_progress_size_; } | ||
62 | |||
63 | - bool has_error() const { return !error_.ok(); } | ||
64 | - | ||
65 | // Set the current error - tweaks the error to include a stream id so that | ||
66 | // chttp2 does not close the connection. | ||
67 | // Intended for errors that are specific to a stream and recoverable. | ||
68 | @@ -246,10 +252,7 @@ class HPackParser::Input { | ||
69 | // read prior to being able to get further in this parse. | ||
70 | void UnexpectedEOF(size_t min_progress_size) { | ||
71 | GPR_ASSERT(min_progress_size > 0); | ||
72 | - if (min_progress_size_ != 0 || error_.connection_error()) { | ||
73 | - GPR_DEBUG_ASSERT(eof_error()); | ||
74 | - return; | ||
75 | - } | ||
76 | + if (eof_error()) return; | ||
77 | // Set min progress size, taking into account bytes parsed already but not | ||
78 | // consumed. | ||
79 | min_progress_size_ = min_progress_size + (begin_ - frontier_); | ||
80 | @@ -302,13 +305,18 @@ class HPackParser::Input { | ||
81 | // Do not use this directly, instead use SetErrorAndContinueParsing or | ||
82 | // SetErrorAndStopParsing. | ||
83 | void SetError(HpackParseResult error) { | ||
84 | - if (!error_.ok() || min_progress_size_ > 0) { | ||
85 | - if (error.connection_error() && !error_.connection_error()) { | ||
86 | - error_ = std::move(error); // connection errors dominate | ||
87 | + SetErrorFor(frame_error_, error); | ||
88 | + SetErrorFor(field_error_, std::move(error)); | ||
89 | + } | ||
90 | + | ||
91 | + void SetErrorFor(HpackParseResult& error, HpackParseResult new_error) { | ||
92 | + if (!error.ok() || min_progress_size_ > 0) { | ||
93 | + if (new_error.connection_error() && !error.connection_error()) { | ||
94 | + error = std::move(new_error); // connection errors dominate | ||
95 | } | ||
96 | return; | ||
97 | } | ||
98 | - error_ = std::move(error); | ||
99 | + error = std::move(new_error); | ||
100 | } | ||
101 | |||
102 | // Refcount if we are backed by a slice | ||
103 | @@ -320,7 +328,8 @@ class HPackParser::Input { | ||
104 | // Frontier denotes the first byte past successfully processed input | ||
105 | const uint8_t* frontier_; | ||
106 | // Current error | ||
107 | - HpackParseResult& error_; | ||
108 | + HpackParseResult& frame_error_; | ||
109 | + HpackParseResult& field_error_; | ||
110 | // If the error was EOF, we flag it here by noting how many more bytes would | ||
111 | // be needed to make progress | ||
112 | size_t min_progress_size_ = 0; | ||
113 | @@ -597,6 +606,7 @@ class HPackParser::Parser { | ||
114 | bool ParseTop() { | ||
115 | GPR_DEBUG_ASSERT(state_.parse_state == ParseState::kTop); | ||
116 | auto cur = *input_->Next(); | ||
117 | + input_->ClearFieldError(); | ||
118 | switch (cur >> 4) { | ||
119 | // Literal header not indexed - First byte format: 0000xxxx | ||
120 | // Literal header never indexed - First byte format: 0001xxxx | ||
121 | @@ -702,7 +712,7 @@ class HPackParser::Parser { | ||
122 | break; | ||
123 | } | ||
124 | gpr_log( | ||
125 | - GPR_DEBUG, "HTTP:%d:%s:%s: %s%s", log_info_.stream_id, type, | ||
126 | + GPR_INFO, "HTTP:%d:%s:%s: %s%s", log_info_.stream_id, type, | ||
127 | log_info_.is_client ? "CLI" : "SVR", memento.md.DebugString().c_str(), | ||
128 | memento.parse_status == nullptr | ||
129 | ? "" | ||
130 | @@ -951,11 +961,10 @@ class HPackParser::Parser { | ||
131 | state_.string_length) | ||
132 | : String::Parse(input_, state_.is_string_huff_compressed, | ||
133 | state_.string_length); | ||
134 | - HpackParseResult& status = state_.frame_error; | ||
135 | absl::string_view key_string; | ||
136 | if (auto* s = absl::get_if<Slice>(&state_.key)) { | ||
137 | key_string = s->as_string_view(); | ||
138 | - if (status.ok()) { | ||
139 | + if (state_.field_error.ok()) { | ||
140 | auto r = ValidateKey(key_string); | ||
141 | if (r != ValidateMetadataResult::kOk) { | ||
142 | input_->SetErrorAndContinueParsing( | ||
143 | @@ -965,7 +974,7 @@ class HPackParser::Parser { | ||
144 | } else { | ||
145 | const auto* memento = absl::get<const HPackTable::Memento*>(state_.key); | ||
146 | key_string = memento->md.key(); | ||
147 | - if (status.ok() && memento->parse_status != nullptr) { | ||
148 | + if (state_.field_error.ok() && memento->parse_status != nullptr) { | ||
149 | input_->SetErrorAndContinueParsing(*memento->parse_status); | ||
150 | } | ||
151 | } | ||
152 | @@ -992,16 +1001,16 @@ class HPackParser::Parser { | ||
153 | key_string.size() + value.wire_size + hpack_constants::kEntryOverhead; | ||
154 | auto md = grpc_metadata_batch::Parse( | ||
155 | key_string, std::move(value_slice), state_.add_to_table, transport_size, | ||
156 | - [key_string, &status, this](absl::string_view message, const Slice&) { | ||
157 | - if (!status.ok()) return; | ||
158 | + [key_string, this](absl::string_view message, const Slice&) { | ||
159 | + if (!state_.field_error.ok()) return; | ||
160 | input_->SetErrorAndContinueParsing( | ||
161 | HpackParseResult::MetadataParseError(key_string)); | ||
162 | gpr_log(GPR_ERROR, "Error parsing '%s' metadata: %s", | ||
163 | std::string(key_string).c_str(), | ||
164 | std::string(message).c_str()); | ||
165 | }); | ||
166 | - HPackTable::Memento memento{std::move(md), | ||
167 | - status.PersistentStreamErrorOrNullptr()}; | ||
168 | + HPackTable::Memento memento{ | ||
169 | + std::move(md), state_.field_error.PersistentStreamErrorOrNullptr()}; | ||
170 | input_->UpdateFrontier(); | ||
171 | state_.parse_state = ParseState::kTop; | ||
172 | if (state_.add_to_table) { | ||
173 | @@ -1163,13 +1172,13 @@ grpc_error_handle HPackParser::Parse( | ||
174 | std::vector<uint8_t> buffer = std::move(unparsed_bytes_); | ||
175 | return ParseInput( | ||
176 | Input(nullptr, buffer.data(), buffer.data() + buffer.size(), bitsrc, | ||
177 | - state_.frame_error), | ||
178 | + state_.frame_error, state_.field_error), | ||
179 | is_last, call_tracer); | ||
180 | } | ||
181 | - return ParseInput( | ||
182 | - Input(slice.refcount, GRPC_SLICE_START_PTR(slice), | ||
183 | - GRPC_SLICE_END_PTR(slice), bitsrc, state_.frame_error), | ||
184 | - is_last, call_tracer); | ||
185 | + return ParseInput(Input(slice.refcount, GRPC_SLICE_START_PTR(slice), | ||
186 | + GRPC_SLICE_END_PTR(slice), bitsrc, state_.frame_error, | ||
187 | + state_.field_error), | ||
188 | + is_last, call_tracer); | ||
189 | } | ||
190 | |||
191 | grpc_error_handle HPackParser::ParseInput( | ||
192 | diff --git a/src/core/ext/transport/chttp2/transport/hpack_parser.h b/src/core/ext/transport/chttp2/transport/hpack_parser.h | ||
193 | index 3745668..55842e4 100644 | ||
194 | --- a/src/core/ext/transport/chttp2/transport/hpack_parser.h | ||
195 | +++ b/src/core/ext/transport/chttp2/transport/hpack_parser.h | ||
196 | @@ -236,6 +236,8 @@ class HPackParser { | ||
197 | HPackTable hpack_table; | ||
198 | // Error so far for this frame (set by class Input) | ||
199 | HpackParseResult frame_error; | ||
200 | + // Error so far for this field (set by class Input) | ||
201 | + HpackParseResult field_error; | ||
202 | // Length of frame so far. | ||
203 | uint32_t frame_length = 0; | ||
204 | // Length of the string being parsed | ||
205 | diff --git a/test/core/transport/chttp2/hpack_parser_test.cc b/test/core/transport/chttp2/hpack_parser_test.cc | ||
206 | index 3772d90..d5b9c6c 100644 | ||
207 | --- a/test/core/transport/chttp2/hpack_parser_test.cc | ||
208 | +++ b/test/core/transport/chttp2/hpack_parser_test.cc | ||
209 | @@ -440,19 +440,82 @@ INSTANTIATE_TEST_SUITE_P( | ||
210 | Test{"Base64LegalEncoding", | ||
211 | {}, | ||
212 | {}, | ||
213 | - {// Binary metadata: created using: | ||
214 | - // tools/codegen/core/gen_header_frame.py | ||
215 | - // --compression inc --no_framing --output hexstr | ||
216 | - // < test/core/transport/chttp2/bad-base64.headers | ||
217 | - {"4009612e622e632d62696e1c6c75636b696c7920666f722075732c206974" | ||
218 | - "27732074756573646179", | ||
219 | - absl::InternalError("Error parsing 'a.b.c-bin' metadata: " | ||
220 | - "illegal base64 encoding"), | ||
221 | - 0}, | ||
222 | - {"be", | ||
223 | - absl::InternalError("Error parsing 'a.b.c-bin' metadata: " | ||
224 | - "illegal base64 encoding"), | ||
225 | - 0}}}, | ||
226 | + { | ||
227 | + // Binary metadata: created using: | ||
228 | + // tools/codegen/core/gen_header_frame.py | ||
229 | + // --compression inc --no_framing --output hexstr | ||
230 | + // < test/core/transport/chttp2/bad-base64.headers | ||
231 | + {"4009612e622e632d62696e1c6c75636b696c7920666f722075732c206974" | ||
232 | + "27732074756573646179", | ||
233 | + absl::InternalError("Error parsing 'a.b.c-bin' metadata: " | ||
234 | + "illegal base64 encoding"), | ||
235 | + 0}, | ||
236 | + {"be", | ||
237 | + absl::InternalError("Error parsing 'a.b.c-bin' metadata: " | ||
238 | + "illegal base64 encoding"), | ||
239 | + kEndOfHeaders}, | ||
240 | + {"82", ":method: GET\n", 0}, | ||
241 | + }}, | ||
242 | + Test{"Base64LegalEncodingWorksAfterFailure", | ||
243 | + {}, | ||
244 | + {}, | ||
245 | + { | ||
246 | + // Binary metadata: created using: | ||
247 | + // tools/codegen/core/gen_header_frame.py | ||
248 | + // --compression inc --no_framing --output hexstr | ||
249 | + // < test/core/transport/chttp2/bad-base64.headers | ||
250 | + {"4009612e622e632d62696e1c6c75636b696c7920666f722075732c206974" | ||
251 | + "27732074756573646179", | ||
252 | + absl::InternalError("Error parsing 'a.b.c-bin' metadata: " | ||
253 | + "illegal base64 encoding"), | ||
254 | + 0}, | ||
255 | + {"be", | ||
256 | + absl::InternalError("Error parsing 'a.b.c-bin' metadata: " | ||
257 | + "illegal base64 encoding"), | ||
258 | + 0}, | ||
259 | + {"400e636f6e74656e742d6c656e6774680135", | ||
260 | + absl::InternalError("Error parsing 'a.b.c-bin' metadata: " | ||
261 | + "illegal base64 encoding"), | ||
262 | + kEndOfHeaders}, | ||
263 | + {"be", "content-length: 5\n", 0}, | ||
264 | + }}, | ||
265 | + Test{"Base64LegalEncodingWorksAfterFailure2", | ||
266 | + {}, | ||
267 | + {}, | ||
268 | + { | ||
269 | + {// Generated with: tools/codegen/core/gen_header_frame.py | ||
270 | + // --compression inc --output hexstr --no_framing < | ||
271 | + // test/core/transport/chttp2/MiXeD-CaSe.headers | ||
272 | + "400a4d695865442d436153651073686f756c64206e6f74207061727365", | ||
273 | + absl::InternalError("Illegal header key: MiXeD-CaSe"), 0}, | ||
274 | + // Binary metadata: created using: | ||
275 | + // tools/codegen/core/gen_header_frame.py | ||
276 | + // --compression inc --no_framing --output hexstr | ||
277 | + // < test/core/transport/chttp2/bad-base64.headers | ||
278 | + {"4009612e622e632d62696e1c6c75636b696c7920666f722075732c206974" | ||
279 | + "27732074756573646179", | ||
280 | + absl::InternalError("Illegal header key: MiXeD-CaSe"), 0}, | ||
281 | + {"be", absl::InternalError("Illegal header key: MiXeD-CaSe"), | ||
282 | + 0}, | ||
283 | + {"400e636f6e74656e742d6c656e6774680135", | ||
284 | + absl::InternalError("Illegal header key: MiXeD-CaSe"), | ||
285 | + kEndOfHeaders}, | ||
286 | + {"be", "content-length: 5\n", 0}, | ||
287 | + {"bf", | ||
288 | + absl::InternalError("Error parsing 'a.b.c-bin' metadata: " | ||
289 | + "illegal base64 encoding"), | ||
290 | + 0}, | ||
291 | + // Only the first error in each frame is reported, so we should | ||
292 | + // still see the same error here... | ||
293 | + {"c0", | ||
294 | + absl::InternalError("Error parsing 'a.b.c-bin' metadata: " | ||
295 | + "illegal base64 encoding"), | ||
296 | + kEndOfHeaders}, | ||
297 | + // ... but if we look at the next frame we should see the | ||
298 | + // stored error | ||
299 | + {"c0", absl::InternalError("Illegal header key: MiXeD-CaSe"), | ||
300 | + kEndOfHeaders}, | ||
301 | + }}, | ||
302 | Test{"TeIsTrailers", | ||
303 | {}, | ||
304 | {}, | ||
305 | diff --git a/test/core/transport/chttp2/hpack_sync_fuzzer.cc b/test/core/transport/chttp2/hpack_sync_fuzzer.cc | ||
306 | index 47e4265..9afa41f 100644 | ||
307 | --- a/test/core/transport/chttp2/hpack_sync_fuzzer.cc | ||
308 | +++ b/test/core/transport/chttp2/hpack_sync_fuzzer.cc | ||
309 | @@ -85,6 +85,10 @@ void FuzzOneInput(const hpack_sync_fuzzer::Msg& msg) { | ||
310 | // Not an interesting case to fuzz | ||
311 | continue; | ||
312 | } | ||
313 | + if (msg.check_ab_preservation() && | ||
314 | + header.literal_inc_idx().key() == "a") { | ||
315 | + continue; | ||
316 | + } | ||
317 | if (absl::EndsWith(header.literal_inc_idx().value(), "-bin")) { | ||
318 | std::ignore = encoder.EmitLitHdrWithBinaryStringKeyIncIdx( | ||
319 | Slice::FromCopiedString(header.literal_inc_idx().key()), | ||
320 | @@ -96,6 +100,10 @@ void FuzzOneInput(const hpack_sync_fuzzer::Msg& msg) { | ||
321 | } | ||
322 | break; | ||
323 | case hpack_sync_fuzzer::Header::kLiteralNotIdx: | ||
324 | + if (msg.check_ab_preservation() && | ||
325 | + header.literal_not_idx().key() == "a") { | ||
326 | + continue; | ||
327 | + } | ||
328 | if (absl::EndsWith(header.literal_not_idx().value(), "-bin")) { | ||
329 | encoder.EmitLitHdrWithBinaryStringKeyNotIdx( | ||
330 | Slice::FromCopiedString(header.literal_not_idx().key()), | ||
331 | @@ -114,6 +122,10 @@ void FuzzOneInput(const hpack_sync_fuzzer::Msg& msg) { | ||
332 | break; | ||
333 | } | ||
334 | } | ||
335 | + if (msg.check_ab_preservation()) { | ||
336 | + std::ignore = encoder.EmitLitHdrWithNonBinaryStringKeyIncIdx( | ||
337 | + Slice::FromCopiedString("a"), Slice::FromCopiedString("b")); | ||
338 | + } | ||
339 | |||
340 | // STAGE 2: Decode the buffer (encode_output) into a list of headers | ||
341 | HPackParser parser; | ||
342 | @@ -140,6 +152,21 @@ void FuzzOneInput(const hpack_sync_fuzzer::Msg& msg) { | ||
343 | } | ||
344 | } | ||
345 | |||
346 | + if (seen_errors.empty() && msg.check_ab_preservation()) { | ||
347 | + std::string backing; | ||
348 | + auto a_value = read_metadata.GetStringValue("a", &backing); | ||
349 | + if (!a_value.has_value()) { | ||
350 | + fprintf(stderr, "Expected 'a' header to be present: %s\n", | ||
351 | + read_metadata.DebugString().c_str()); | ||
352 | + abort(); | ||
353 | + } | ||
354 | + if (a_value != "b") { | ||
355 | + fprintf(stderr, "Expected 'a' header to be 'b', got '%s'\n", | ||
356 | + std::string(*a_value).c_str()); | ||
357 | + abort(); | ||
358 | + } | ||
359 | + } | ||
360 | + | ||
361 | // STAGE 3: If we reached here we either had a stream error or no error | ||
362 | // parsing. | ||
363 | // Either way, the hpack tables should be of the same size between client and | ||
364 | @@ -168,6 +195,41 @@ void FuzzOneInput(const hpack_sync_fuzzer::Msg& msg) { | ||
365 | } | ||
366 | abort(); | ||
367 | } | ||
368 | + | ||
369 | + if (msg.check_ab_preservation()) { | ||
370 | + SliceBuffer encode_output_2; | ||
371 | + hpack_encoder_detail::Encoder encoder_2( | ||
372 | + &compressor, msg.use_true_binary_metadata(), encode_output_2); | ||
373 | + encoder_2.EmitIndexed(62); | ||
374 | + GPR_ASSERT(encode_output_2.Count() == 1); | ||
375 | + grpc_metadata_batch read_metadata_2(arena.get()); | ||
376 | + parser.BeginFrame( | ||
377 | + &read_metadata_2, 1024, 1024, HPackParser::Boundary::EndOfHeaders, | ||
378 | + HPackParser::Priority::None, | ||
379 | + HPackParser::LogInfo{3, HPackParser::LogInfo::kHeaders, false}); | ||
380 | + auto err = parser.Parse(encode_output_2.c_slice_at(0), true, | ||
381 | + absl::BitGenRef(proto_bit_src), | ||
382 | + /*call_tracer=*/nullptr); | ||
383 | + if (!err.ok()) { | ||
384 | + fprintf(stderr, "Error parsing preservation encoded data: %s\n", | ||
385 | + err.ToString().c_str()); | ||
386 | + abort(); | ||
387 | + } | ||
388 | + std::string backing; | ||
389 | + auto a_value = read_metadata_2.GetStringValue("a", &backing); | ||
390 | + if (!a_value.has_value()) { | ||
391 | + fprintf(stderr, | ||
392 | + "Expected 'a' header to be present: %s\nfirst metadata: %s\n", | ||
393 | + read_metadata_2.DebugString().c_str(), | ||
394 | + read_metadata.DebugString().c_str()); | ||
395 | + abort(); | ||
396 | + } | ||
397 | + if (a_value != "b") { | ||
398 | + fprintf(stderr, "Expected 'a' header to be 'b', got '%s'\n", | ||
399 | + std::string(*a_value).c_str()); | ||
400 | + abort(); | ||
401 | + } | ||
402 | + } | ||
403 | } | ||
404 | |||
405 | } // namespace | ||
406 | diff --git a/test/core/transport/chttp2/hpack_sync_fuzzer.proto b/test/core/transport/chttp2/hpack_sync_fuzzer.proto | ||
407 | index 72792b6..2c075a6 100644 | ||
408 | --- a/test/core/transport/chttp2/hpack_sync_fuzzer.proto | ||
409 | +++ b/test/core/transport/chttp2/hpack_sync_fuzzer.proto | ||
410 | @@ -44,4 +44,7 @@ message Msg { | ||
411 | repeated Header headers = 2; | ||
412 | grpc.testing.FuzzConfigVars config_vars = 3; | ||
413 | repeated uint64 random_numbers = 4; | ||
414 | + // Ensure that a header "a: b" appended to headers with hpack incremental | ||
415 | + // indexing is correctly added to the hpack table. | ||
416 | + bool check_ab_preservation = 5; | ||
417 | } | ||
418 | -- | ||
419 | 2.44.1 | ||
420 | |||
diff --git a/meta-oe/recipes-devtools/grpc/grpc_1.60.1.bb b/meta-oe/recipes-devtools/grpc/grpc_1.60.1.bb index 63c696a623..4557fcc908 100644 --- a/meta-oe/recipes-devtools/grpc/grpc_1.60.1.bb +++ b/meta-oe/recipes-devtools/grpc/grpc_1.60.1.bb | |||
@@ -24,6 +24,7 @@ SRCREV_grpc = "e5ae3b6b44bf3b64d24bfb4b4f82556239b986db" | |||
24 | BRANCH = "v1.60.x" | 24 | BRANCH = "v1.60.x" |
25 | SRC_URI = "gitsm://github.com/grpc/grpc.git;protocol=https;name=grpc;branch=${BRANCH} \ | 25 | SRC_URI = "gitsm://github.com/grpc/grpc.git;protocol=https;name=grpc;branch=${BRANCH} \ |
26 | file://0001-cmake-Link-with-libatomic-on-rv32-rv64.patch \ | 26 | file://0001-cmake-Link-with-libatomic-on-rv32-rv64.patch \ |
27 | file://CVE-2024-7246.patch \ | ||
27 | " | 28 | " |
28 | # Fixes build with older compilers 4.8 especially on ubuntu 14.04 | 29 | # Fixes build with older compilers 4.8 especially on ubuntu 14.04 |
29 | CXXFLAGS:append:class-native = " -Wl,--no-as-needed" | 30 | CXXFLAGS:append:class-native = " -Wl,--no-as-needed" |