Skip to content

Add rudimentary fuzz test for service control filter #55

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

Merged
merged 5 commits into from
Mar 6, 2020

Conversation

nareddyt
Copy link
Contributor

@nareddyt nareddyt commented Mar 6, 2020

  • Fuzz the entire service control filter config and upstream/downstream/sidestream requests.
  • Add some initial valid values to the corpus to kick-start OSS-Fuzz. After running locally for 5 minutes, 69% of lines are covered.
  • This test is very rudimentary and has some items that can be improved (see inline TODOs and FIXMEs). Currently, this is very slow when running locally (4 exec/s).

Signed-off-by: Teju Nareddy [email protected]

nareddyt added 2 commits March 5, 2020 16:48
Notes:
- Fuzz the entire service control filter config and upstream/downstream/sidestream requests.
- Add some initial valid values to the corpus to kick-start OSS-Fuzz. After running locally for 5 minutes, 66% of lines are covered.
- This test is very rudimentary and has some items that can be improved (see inline TODOs and FIXMEs). Currently, this is very slow when running locally (4 exec/s).

Signed-off-by: Teju Nareddy <[email protected]>
Signed-off-by: Teju Nareddy <[email protected]>
Copy link

@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.

Love it!!! This is great.

Will probably take a second pass looking more closely at the mocks, but the less expectations you can make and the more (safe, by cleaning-up) statics you can make, the faster it will be

TestStreamInfo stream_info =
Envoy::Fuzz::fromStreamInfo(input.stream_info());
EXPECT_CALL(mock_decoder_callbacks, streamInfo())
.WillRepeatedly(ReturnRef(stream_info));
Copy link

Choose a reason for hiding this comment

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

Instead of setting expectation (slow-down), can you set mock_decoder_callbacks.stream_info_ = stream_info, the expectation to return stream_info_ is already made in initialization. Does this speed-up?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Unfortunately, this didn't work due to mocks vs fakes.

src/envoy/http/service_control/filter_fuzz_test.cc:182:41: error: no match for 'operator=' (operand types are 'testing::NiceMock<Envoy::StreamInfo::MockStreamInfo>' and 'Envoy::TestStreamInfo')
  182 |   mock_decoder_callbacks.stream_info_ = stream_info;

Copy link

Choose a reason for hiding this comment

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

Ahhhh. Gotcha. Didn't realize stream_info_ was a mock. Boo.

I think this is fine as is as a start, and you can iterat for speed ups. I think it'll be possible to make some of the mocks and expectations static and updating/cleaning up per-run, but it's a good task to iterate on.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point, could you share an example of this in Envoy? I'm not familiar with how this will speed up execution.

Yup, I can iterate on this next week. I'd like to get this merged first so OSS-Fuzz will pick it up and display some initial fuzz stats.

Copy link

Choose a reason for hiding this comment

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

Sounds like a plan!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As discussed offline: envoyproxy/envoy#8397

nareddyt added 2 commits March 6, 2020 10:44
Signed-off-by: Teju Nareddy <[email protected]>
Signed-off-by: Teju Nareddy <[email protected]>
!input.downstream_request().has_trailers()) {
end_stream = true;
}
filter.decodeHeaders(downstream_headers, end_stream);
Copy link

Choose a reason for hiding this comment

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

And then similarly, is there any reason to consider the filter status in case there's a reason to stop decoding?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not for this filter, we only ever StopIteration or Continue, and that will probably never change. Our filter should support all 3 being called.

Copy link
Contributor

Choose a reason for hiding this comment

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

why do we need to make sure end_stream is correct? Sometime, due to bug, end_stream may not called correctly. we still need to fuzz these data flow.

Copy link

Choose a reason for hiding this comment

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

Are you saying it's possible to execute decodeHeaders(_, true) and then decodeData(_, _) somewhere?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@qiwzhang I think it's reasonable to expect end_stream is set correctly, this is part of the Envoy filter API. If it's set incorrectly, some upstream filters would not function. I don't think this will ever happen, but we can fuzz it if you believe it can.

@nareddyt nareddyt requested a review from qiwzhang March 6, 2020 19:52
Signed-off-by: Teju Nareddy <[email protected]>
Copy link

@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.

LGTM modulo the discussion about fuzzing the execution path decodeHeaders(_,true) then decodeData(_,_). Will defer to Wayne.

@google-oss-robot
Copy link
Collaborator

@asraa: changing LGTM is restricted to collaborators

In response to this:

LGTM modulo the discussion about fuzzing the execution path decodeHeaders(_,true) then decodeData(_,_). Will defer to Wayne.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@google-oss-robot
Copy link
Collaborator

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: asraa, nareddyt, qiwzhang

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@nareddyt nareddyt merged commit 5331f0e into GoogleCloudPlatform:master Mar 6, 2020
@nareddyt nareddyt deleted the sc-fuzz branch March 6, 2020 21:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants