Skip to content

fuzz: replace invalid characters in upstream metadata for header parser#7436

Merged
mattklein123 merged 4 commits intoenvoyproxy:masterfrom
asraa:headerparserfuzz
Jul 29, 2019
Merged

fuzz: replace invalid characters in upstream metadata for header parser#7436
mattklein123 merged 4 commits intoenvoyproxy:masterfrom
asraa:headerparserfuzz

Conversation

@asraa
Copy link
Copy Markdown
Contributor

@asraa asraa commented Jul 1, 2019

Replace invalid header characters in filter metadata strings.

Risk Level: Low
Testing: Add corpus entry
Fixes OSS-Fuzz issue:
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=15555

asraa added 2 commits July 1, 2019 14:08
Signed-off-by: Asra Ali <asraa@google.com>
@junr03
Copy link
Copy Markdown
Member

junr03 commented Jul 2, 2019

@venilnoronha can you give this a first pass?

@venilnoronha
Copy link
Copy Markdown
Member

@junr03 will do.

@venilnoronha
Copy link
Copy Markdown
Member

@asraa I don't seem to have access to https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=15555. Can you grant me/fill me about what exactly this PR is fixing?

@asraa
Copy link
Copy Markdown
Contributor Author

asraa commented Jul 3, 2019

@asraa I don't seem to have access to https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=15555. Can you grant me/fill me about what exactly this PR is fixing?

Yes! Sorry about that. The added testcase causes a crash because of the null character here. Because we are trying to add an "%UPSTREAM_METADATA(...)" header, we move the values of the metadata into headers, and this crashes since headers must be "valid()" (not contain null / newline characters). Here's the stack trace:

[2019-06-08 14:53:26.859][1][critical][assert] [source/common/http/header_map_impl.cc:209] assert failure: valid().
  | AddressSanitizer:DEADLYSIGNAL
  | =================================================================
  | ==1==ERROR: AddressSanitizer: ABRT on unknown address 0x000000000001 (pc 0x7fadbb19c428 bp 0x7ffe42257b30 sp 0x7ffe42257968 T0)
  | SCARINESS: 10 (signal)
  | #0 0x7fadbb19c427 in gsignal /build/glibc-LK5gWL/glibc-2.23/sysdeps/unix/sysv/linux/raise.c:54
  | #1 0x7fadbb19e029 in abort /build/glibc-LK5gWL/glibc-2.23/stdlib/abort.c:89
  | #2 0x1c0c23e in Envoy::Http::HeaderString::setCopy(char const*, unsigned int) /proc/self/cwd/source/common/http/header_map_impl.cc:0
  | #3 0x1c110b3 in Envoy::Http::HeaderMapImpl::setReferenceKey(Envoy::Http::LowerCaseString const&, std::__1::basic_string<char, std::__1::char_traits, std::__1::allocator > const&) /proc/self/cwd/source/common/http/header_map_impl.cc:448:13
  | #4 0x148fd60 in Envoy::Router::HeaderParser::evaluateHeaders(Envoy::Http::HeaderMap&, Envoy::StreamInfo::StreamInfo const&) const /proc/self/cwd/source/common/router/header_parser.cc:269:17
  | #5 0x504e16 in Envoy::Fuzz::(anonymous namespace)::TestOneProtoInput(test::common::router::TestCase const&) /proc/self/cwd/test/common/router/header_parser_fuzz_test.cc:25:13

envoy::api::v2::core::Metadata processed = upstream_metadata;
for (auto& metadata_struct : *processed.mutable_filter_metadata()) {
for (auto& field : *metadata_struct.second.mutable_fields()) {
if (field.second.kind_case() == ProtobufWkt::Value::kStringValue) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't too concerned with this as an issue to fuzz over since metadata usually comes from the config (e.g. listenerMetadata(), or routeEntry metadata) or from the connection's streaminfo, so it'd be on the onus of the one configuring Envoy to make sure there's no NUL characters. I would have handled them only if the fuzzer gets blocked on them, but I'm not sure how complicated the fuzzer will get for this case. I could handle them, though, if you think it'd be easier to get done in one PR

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can skip this for now then. @junr03 thoughts?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hey! just a ping, would love to move forward.
thanks!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@asraa could you please leave a note related to the discussion above? Thanks!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done! Thank you.

fields {
key: ""
value {
string_value: "c\000\000\000\000\000\000\000"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if it's required. Do you think we need test cases for recursive (struct, list, etc.) types?

@stale
Copy link
Copy Markdown

stale bot commented Jul 22, 2019

This pull request has been automatically marked as stale because it has not had activity in the last 7 days. It will be closed in 7 days if no further activity occurs. Please feel free to give a status update now, ping for review, or re-open when it's ready. Thank you for your contributions!

@stale stale bot added the stale stalebot believes this issue/PR has not been touched recently label Jul 22, 2019
@dio dio removed the stale stalebot believes this issue/PR has not been touched recently label Jul 22, 2019
Signed-off-by: Asra Ali <asraa@google.com>
for (auto& metadata_struct : *processed.mutable_filter_metadata()) {
// Metadata fields consist of keyed Structs, which is a map of dynamically typed values. These
// values can be null, a number, a string, a boolean, a list of values, or a recursive struct.
// This clears any invalid characters in string values. It may not be likely a coverage-driven
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/It may/It may (two space characters between It and may)

Signed-off-by: Asra Ali <asraa@google.com>
@asraa
Copy link
Copy Markdown
Contributor Author

asraa commented Jul 29, 2019

/retest

@repokitteh-read-only
Copy link
Copy Markdown

🔨 rebuilding ci/circleci: asan (failed build)

🐱

Caused by: a #7436 (comment) was created by @asraa.

see: more, trace.

Copy link
Copy Markdown
Member

@dio dio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉

@mattklein123 mattklein123 merged commit b122e9a into envoyproxy:master Jul 29, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants