Fix handling of very long user-agent strings (#28376)

* fix encoding of very long user-agent strings

* fuzzer found example
pull/28416/head
Craig Tiller 3 years ago committed by GitHub
parent c95ed2ebcb
commit fb54d04ae2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 7
      src/core/ext/transport/chttp2/transport/hpack_encoder.cc
  2. 2
      src/core/ext/transport/chttp2/transport/hpack_encoder_table.cc
  3. 2
      src/core/ext/transport/chttp2/transport/hpack_encoder_table.h
  4. 350
      test/core/end2end/fuzzers/api_fuzzer_corpus/alloc-idx

@ -26,6 +26,7 @@
#include <cstdint> #include <cstdint>
#include "hpack_constants.h" #include "hpack_constants.h"
#include "hpack_encoder_table.h"
/* This is here for grpc_is_binary_header /* This is here for grpc_is_binary_header
* TODO(murgatroid99): Remove this * TODO(murgatroid99): Remove this
@ -759,6 +760,12 @@ void HPackCompressor::Framer::Encode(GrpcTimeoutMetadata,
} }
void HPackCompressor::Framer::Encode(UserAgentMetadata, const Slice& slice) { void HPackCompressor::Framer::Encode(UserAgentMetadata, const Slice& slice) {
if (slice.length() > HPackEncoderTable::MaxEntrySize()) {
EmitLitHdrWithNonBinaryStringKeyNotIdx(
StaticSlice::FromStaticString(UserAgentMetadata::key()).c_slice(),
slice.c_slice());
return;
}
if (!slice.is_equivalent(compressor_->user_agent_)) { if (!slice.is_equivalent(compressor_->user_agent_)) {
compressor_->user_agent_ = slice.Ref(); compressor_->user_agent_ = slice.Ref();
compressor_->user_agent_index_ = 0; compressor_->user_agent_index_ = 0;

@ -22,7 +22,7 @@ namespace grpc_core {
uint32_t HPackEncoderTable::AllocateIndex(size_t element_size) { uint32_t HPackEncoderTable::AllocateIndex(size_t element_size) {
uint32_t new_index = tail_remote_index_ + table_elems_ + 1; uint32_t new_index = tail_remote_index_ + table_elems_ + 1;
GPR_DEBUG_ASSERT(element_size < 65536); GPR_DEBUG_ASSERT(element_size <= MaxEntrySize());
if (element_size > max_table_size_) { if (element_size > max_table_size_) {
while (table_size_ > 0) { while (table_size_ > 0) {

@ -29,6 +29,8 @@ class HPackEncoderTable {
public: public:
HPackEncoderTable() : elem_size_(hpack_constants::kInitialTableEntries) {} HPackEncoderTable() : elem_size_(hpack_constants::kInitialTableEntries) {}
static constexpr size_t MaxEntrySize() { return 65535; }
// Reserve space in table for the new element, evict entries if needed. // Reserve space in table for the new element, evict entries if needed.
// Return the new index of the element. Return 0 to indicate not adding to // Return the new index of the element. Return 0 to indicate not adding to
// table. // table.

File diff suppressed because one or more lines are too long
Loading…
Cancel
Save