From 99e833d751e060caaac948302538b2b6392e1a4e Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Thu, 23 Dec 2021 10:26:17 -0800 Subject: [PATCH] Better handle invalid content-type (#28377) --- .../chttp2/transport/hpack_encoder.cc | 5 ++- src/core/lib/transport/metadata_batch.h | 13 ++++++- .../testcase-4902018028535808 | 35 +++++++++++++++++++ 3 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 test/core/end2end/fuzzers/api_fuzzer_corpus/testcase-4902018028535808 diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.cc b/src/core/ext/transport/chttp2/transport/hpack_encoder.cc index 60f3ad15441..69aa35acf5f 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.cc @@ -611,7 +611,10 @@ void HPackCompressor::Framer::Encode(TeMetadata, TeMetadata::ValueType value) { void HPackCompressor::Framer::Encode(ContentTypeMetadata, ContentTypeMetadata::ValueType value) { - GPR_ASSERT(value == ContentTypeMetadata::ValueType::kApplicationGrpc); + if (value != ContentTypeMetadata::ValueType::kApplicationGrpc) { + gpr_log(GPR_ERROR, "Not encoding bad content-type header"); + return; + } EncodeAlwaysIndexed( &compressor_->content_type_index_, GRPC_MDSTR_CONTENT_TYPE, StaticSlice::FromStaticString("application/grpc").c_slice(), diff --git a/src/core/lib/transport/metadata_batch.h b/src/core/lib/transport/metadata_batch.h index fbc1d56186f..9d634defb77 100644 --- a/src/core/lib/transport/metadata_batch.h +++ b/src/core/lib/transport/metadata_batch.h @@ -888,12 +888,23 @@ class MetadataMap { template void Encode(Which, const typename Which::ValueType& value) { - size_ += Which::key().length() + Which::Encode(value).length() + 32; + Add(Which(), value); + } + + void Encode(ContentTypeMetadata, + const typename ContentTypeMetadata::ValueType& value) { + if (value == ContentTypeMetadata::kInvalid) return; + Add(ContentTypeMetadata(), value); } size_t size() const { return size_; } private: + template + void Add(Which, const typename Which::ValueType& value) { + size_ += Which::key().length() + Which::Encode(value).length() + 32; + } + uint32_t size_ = 0; }; diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/testcase-4902018028535808 b/test/core/end2end/fuzzers/api_fuzzer_corpus/testcase-4902018028535808 new file mode 100644 index 00000000000..e8a4b0c7b13 --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/testcase-4902018028535808 @@ -0,0 +1,35 @@ +actions { + create_channel { + target: "unix:" + channel_actions { + add_n_bytes_writable: 42932895744 + add_n_bytes_readable: 34359738368 + } + } +} +actions { + create_call { + propagation_mask: 9869440 + method { + value: "v" + intern: true + } + timeout: 1000000000 + } +} +actions { + queue_batch { + operations { + send_initial_metadata { + metadata { + key { + value: "content-type" + } + value { + value: "u-bin" + } + } + } + } + } +}