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

[filters] Add RBAC condition fuzzer (CEL expressions) #8752

Closed
wants to merge 6 commits into from

Conversation

asraa
Copy link
Contributor

@asraa asraa commented Oct 24, 2019

This adds a fuzzer for CEL expression matching. These conditions are used in the RBAC filter for complementing the existing principal/permission model.

About a quarter of the execution time is coming from google::api::expr::runtime::RegisterBuiltinFunctions. The test runs locally at about 250 exec/sec.

See: #7716

Risk Level: Low
Testing: Converted unit tests into corpus entries

@asraa
Copy link
Contributor Author

asraa commented Oct 24, 2019

/review @kyessenov

} else {
return CelValue::CreateString(info_.downstreamRemoteAddress()->asStringView());
if (info_.downstreamLocalAddress() != nullptr) {
Copy link
Contributor

Choose a reason for hiding this comment

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

downstreamRemoteAddress?


// Create the CEL expression.
Protobuf::Arena arena;
Expr::BuilderPtr builder = Expr::createBuilder(&arena);
Copy link
Contributor

Choose a reason for hiding this comment

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

You can move the builder out of the loop. It reuses the constant arena, so you might want to disable constant folding to reduce interference.

@@ -157,9 +157,13 @@ absl::optional<CelValue> PeerWrapper::operator[](CelValue key) const {
auto value = key.StringOrDie().value();
if (value == Address) {
if (local_) {
return CelValue::CreateString(info_.downstreamLocalAddress()->asStringView());
if (info_.downstreamLocalAddress() != nullptr) {
return CelValue::CreateString(info_.downstreamLocalAddress()->asStringView());
Copy link
Contributor

Choose a reason for hiding this comment

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

This is fine, but the stream info header states both can never be null.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah OK. Should be fine then now since TestStreamInfo sets both. Originally it caught a ubsan bug when it wasn't set. Changed, since the fuzzer shouldn't hit that case.

@@ -96,7 +96,7 @@ absl::optional<CelValue> ResponseWrapper::operator[](CelValue key) const {
return CelValue::CreateInt64(code.value());
}
} else if (value == Size) {
return CelValue::CreateInt64(info_.bytesSent());
return CelValue::CreateUint64(info_.bytesSent());
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we leave this to be int64? It makes inter-op with other int64 values better. Otherwise, we have to cast in the expressions to int64, which is annoying.

@asraa
Copy link
Contributor Author

asraa commented Oct 28, 2019

@kyessenov are comprehension expressions supported? It seems like they aren't because ListKeys isn't implemented for e.g. with request maps.
Is it documented which expressions aren't supported? I might throw an EnvoyException in createExpression if they aren't supported.

@kyessenov
Copy link
Contributor

@asraa Comprehensions are explicitly disabled as of #8746 since they can cause non-linear resource complexity. Same for string/list concatenations. I think you should get an exception building an expression for comprehensions, but not string/list concatenations. That's because string/list concat shares the operator + with normal addition (which is a language issue, that is being discussed). In any case, the evaluator should still successfully produce an error as a result of create expression or eval expression.

asraa added 5 commits October 28, 2019 15:08
Signed-off-by: Asra Ali <[email protected]>
Signed-off-by: Asra Ali <[email protected]>
Signed-off-by: Asra Ali <[email protected]>
Signed-off-by: Asra Ali <[email protected]>
@asraa
Copy link
Contributor Author

asraa commented Oct 28, 2019

Gotcha thanks! Thanks for that PR. I updated the branch and added the testcase that was failing from the comprehension expressions. Should be good now.

@kyessenov
Copy link
Contributor

Changes look fine to me, but I'm not very familiar with the fuzzing framework. Let me know if the fuzzer detects something.

@asraa
Copy link
Contributor Author

asraa commented Oct 28, 2019

Will do. After about a day of being checked in to upstream, OSS-Fuzz will report any crashes that come up. I'll reach out to you with anything that comes up. Also feel free to ping me if you want to extend fuzzers for the filter.

@stale
Copy link

stale bot commented Nov 4, 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 Nov 4, 2019
@@ -187,6 +187,7 @@ absl::optional<CelValue> PeerWrapper::operator[](CelValue key) const {
if (value == Address) {
if (local_) {
return CelValue::CreateString(info_.downstreamLocalAddress()->asStringView());

Copy link
Contributor

Choose a reason for hiding this comment

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

extra new line

Copy link
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!

@stale stale bot removed the stale stalebot believes this issue/PR has not been touched recently label Nov 4, 2019
@repokitteh-read-only
Copy link

CC @envoyproxy/api-shepherds: Your approval is needed for changes made to api/.

🐱

Caused by: #8752 was synchronize by asraa.

see: more, trace.

Signed-off-by: Asra Ali <[email protected]>
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.

Generally this looks great, nice fuzzer design. Just some comments/clarification requests and then LGTM.


DEFINE_PROTO_FUZZER(const test::extensions::filters::common::expr::EvaluatorTestCase& input) {
// Create builder without constant folding.
static Expr::BuilderPtr builder = Expr::createBuilder(nullptr);
Copy link
Member

Choose a reason for hiding this comment

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

Is this stateless? I.e. it won't vary between test cases and so is safe to make static? If so, please update the above comment.

Copy link
Contributor

Choose a reason for hiding this comment

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

Builder can be shared between expressions.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated comment. Yep, it was time-consuming to create the builder between iterations as well, so I felt it was a worthy object to make static.

Http::TestHeaderMapImpl response_trailers = Fuzz::fromHeaders(input.trailers());

// Evaluate the CEL expression.
Protobuf::Arena arena;
Copy link
Member

Choose a reason for hiding this comment

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

What is this for?

Copy link
Contributor

Choose a reason for hiding this comment

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

CEL creates all temporary objects on an arena. I think this is used for this purpose.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated, passed in to evaluate. I was playing around with which would be faster.

@stale
Copy link

stale bot commented Nov 13, 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 Nov 13, 2019
@stale
Copy link

stale bot commented Nov 20, 2019

This pull request has been automatically closed because it has not had activity in the last 14 days. 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 closed this Nov 20, 2019
@asraa
Copy link
Contributor Author

asraa commented Nov 22, 2019

Sorry it passed through my attention until it was marked closed!! Should be ready now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api stale stalebot believes this issue/PR has not been touched recently
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants