Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixing HCM fuzzer ContinueAndEndStream with end_stream set #11497

Merged
merged 13 commits into from
Jun 19, 2020

Conversation

adisuissa
Copy link
Contributor

Fixing the HCM fuzzer to avoid cases where its decodeHeaders method returns FilterHeadersStatus::ContinueAndEndStream when called with end_stream=true.
This assert was added in #4885, to avoid misuse of the FilterHeadersStatus::ContinueAndEndStream value.

Risk Level: Low - tests only
Testing: Changed HCM fuzzer test code
Fixes oss fuzz issue 21971

Signed-off-by: Adi Suissa-Peleg adip@google.com

Signed-off-by: Adi Suissa-Peleg <adip@google.com>
@adisuissa
Copy link
Contributor Author

@asraa please take a look, and let me know if you think something else should've been done

Signed-off-by: Adi Suissa-Peleg <adip@google.com>
Copy link
Contributor

@asraa asraa left a comment

Choose a reason for hiding this comment

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

Thanks Adi! Interesting, I think this is correct based on matching HCM behavior in the fuzzer since the ASSERT is enforcing this "should-be" behavior.

I'm not sure if this ASSERT is really enforcing a true invariant, though. Maybe add this to the docstring for this status in include/envoy/http/filter.h so filter devs don't violate?

test/common/http/conn_manager_impl_fuzz_test.cc Outdated Show resolved Hide resolved
test/common/http/conn_manager_impl_fuzz_test.cc Outdated Show resolved Hide resolved
@adisuissa
Copy link
Contributor Author

Giving this another thought, and I'm not sure if we should keep the assert in cases where a dynamically loaded filter will return FilterHeadersStatus::ContinueAndEndStream with end_stream=true.
@antoniovicente could use your advice on whether dynamic filters can trigger the assert

Signed-off-by: Adi Suissa-Peleg <adip@google.com>
…20200604

Signed-off-by: Adi Suissa-Peleg <adip@google.com>
Signed-off-by: Adi Suissa-Peleg <adip@google.com>
Signed-off-by: Adi Suissa-Peleg <adip@google.com>
@adisuissa
Copy link
Contributor Author

@asraa @htuch please take a look at the FAQ, and let me know if it should be modified

Is there a contract my HTTP filter must adhere to?
==================================================

* A filter's ``decodeData`` implementation must not return ``FilterHeadersStatus::ContinueAndEndStream`` when called with ``end_stream`` set.
Copy link
Member

Choose a reason for hiding this comment

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

There are a bunch more in https://github.com/envoyproxy/envoy/blob/master/include/envoy/http/filter.h that might be worth re-iterating. E.g. the StopIteration contract, which headers you can safely expect to exist in decodeHeaders() (e.g. Path? Host?).

@envoyproxy/maintainers what other contracts exist here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added notes about:

  • headers encoding/decoding
  • data encoding/decoding
  • trailers encoding/decoding
  • known headers: Host and Path (optional for CONNECT requests).
    Anything else that comes to mind?

Signed-off-by: Adi Suissa-Peleg <adip@google.com>
…20200604

Signed-off-by: Adi Suissa-Peleg <adip@google.com>
…20200604

Signed-off-by: Adi Suissa-Peleg <adip@google.com>
Signed-off-by: Adi Suissa-Peleg <adip@google.com>
Signed-off-by: Adi Suissa-Peleg <adip@google.com>
Copy link
Contributor

@asraa asraa left a comment

Choose a reason for hiding this comment

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

Thanks so much Adi!

docs/root/faq/extensions/contract.rst Outdated Show resolved Hide resolved
Signed-off-by: Adi Suissa-Peleg <adip@google.com>
----------------------------------------------------------------------------------------------

Yes. The map must contain the following headers: ``Host``, ``Path`` (this might be omitted for
CONNECT requests).
Copy link
Member

Choose a reason for hiding this comment

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

@alyssawilk does this cover all relevant aspects of the contract here?

Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Contributor

Choose a reason for hiding this comment

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

Currently the Envoy constraints are that the first filter receiving decodeHeaders will have a Host and if non-CONNECT it will have a Path. That said there's nothing stopping a user-defined filter from removing either (though the codec may crash or throw when trying to serialize incomplete headers if a later filter doesn't add it back) as the HCM will not validate before passing to the next filter.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the clarification.
I've updated the text as follows:

The first filter of the decoding filter chain will have the following headers in the map:

  • Host
  • Path (this might be omitted for CONNECT requests).

Although these headers may be omitted by one of the filters on the decoding filter chain,
they should be reinserted before the terminal filter is triggered.

Copy link
Member

@htuch htuch left a comment

Choose a reason for hiding this comment

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

Thanks! Looks good, just want to verify we have the headers contract details fully correct, since we have seen serious bugs here before.

Signed-off-by: Adi Suissa-Peleg <adip@google.com>
Copy link
Member

@htuch htuch left a comment

Choose a reason for hiding this comment

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

LGTM, thanks!

@htuch htuch merged commit cfb163d into envoyproxy:master Jun 19, 2020
songhu pushed a commit to songhu/envoy that referenced this pull request Jun 25, 2020
…y#11497)

Fixing the HCM fuzzer to avoid cases where its decodeHeaders method returns FilterHeadersStatus::ContinueAndEndStream when called with end_stream=true.
This assert was added in envoyproxy#4885, to avoid misuse of the FilterHeadersStatus::ContinueAndEndStream value.

Risk Level: Low - tests only
Testing: Changed HCM fuzzer test code
Fixes oss fuzz issue 21971

Signed-off-by: Adi Suissa-Peleg <adip@google.com>
yashwant121 pushed a commit to yashwant121/envoy that referenced this pull request Jul 24, 2020
…y#11497)

Fixing the HCM fuzzer to avoid cases where its decodeHeaders method returns FilterHeadersStatus::ContinueAndEndStream when called with end_stream=true.
This assert was added in envoyproxy#4885, to avoid misuse of the FilterHeadersStatus::ContinueAndEndStream value.

Risk Level: Low - tests only
Testing: Changed HCM fuzzer test code
Fixes oss fuzz issue 21971

Signed-off-by: Adi Suissa-Peleg <adip@google.com>
Signed-off-by: yashwant121 <yadavyashwant36@gmail.com>
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.

4 participants