Skip to content

Conversation

adisuissa
Copy link
Contributor

Verifying that the sum of weights in the configuration file isn't over uint32_t maximal value.
If the sum is overflowing, an exception is thrown.

Risk Level: Low
Testing: None
Fixes fuzz test: 5702999713513472

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

… value

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

/cc @asraa @snowp
If you think of a better way to verify overflow, or if there's a way to validate it using proto validators, please let me know.
Also, couldn't find the unit-tests of the weights configuration, so if there is a file that you are aware of, I'll add new tests to it.

Copy link
Contributor

@snowp snowp left a comment

Choose a reason for hiding this comment

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

Thanks this looks like a reasonable fix to me.

for (const auto& host : hosts) {
sum += host->weight();
if (sum > std::numeric_limits<uint32_t>::max()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This seems like a fine way to check for overflow (the other one I could think of would be if (sum + host->weight() >= sum) with sum being uint32_t).

Can you make sure both this and the other exception has coverage and if not add a unit test?

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 @snowp !
I agree that we can check if sum is increasing, but I think the current option clarifies that we check for an overflow.

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

Added tests for the new exceptions

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

@snowp snowp left a comment

Choose a reason for hiding this comment

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

Thanks this looks good, just a comment on the error message

for (const auto weight : locality_weights) {
sum += weight;
if (sum > std::numeric_limits<uint32_t>::max()) {
throw EnvoyException(
fmt::format("Load balancing locality weights has accumulated over its maximum value {}",
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this error message could be a bit clearer: it might not be obvious to an operator that these weights are being accumulated. Maybe the message should be around the fact that the sum of locality weights within a priority causing overflow? Similar with host weights, though I'm not sure what the invariant is there (per locality? per priority?)

@snowp
Copy link
Contributor

snowp commented Apr 2, 2020

Also: @envoyproxy/api-shepherds is this something we'd want to be documenting on the protos? Or are we okay with this just failing validation if it happens?

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

adisuissa commented Apr 3, 2020

Changed the error messages according to:

// The optional load balancing weight of the upstream host; at least 1.
// Envoy uses the load balancing weight in some of the built in load
// balancers. The load balancing weight for an endpoint is divided by the sum
// of the weights of all endpoints in the endpoint's locality to produce a
// percentage of traffic for the endpoint. This percentage is then further
// weighted by the endpoint's locality's load balancing weight from
// LocalityLbEndpoints. If unspecified, each host is presumed to have equal
// weight in a locality.
google.protobuf.UInt32Value load_balancing_weight = 4 [(validate.rules).uint32 = {gte: 1}];

and

// Optional: Per priority/region/zone/sub_zone weight; at least 1. The load
// balancing weight for a locality is divided by the sum of the weights of all
// localities at the same priority level to produce the effective percentage
// of traffic for the locality.
//
// Locality weights are only considered when :ref:`locality weighted load
// balancing <arch_overview_load_balancing_locality_weighted_lb>` is
// configured. These weights are ignored otherwise. If no weights are
// specified when locality weighted load balancing is enabled, the locality is
// assigned no load.
google.protobuf.UInt32Value load_balancing_weight = 3 [(validate.rules).uint32 = {gte: 1}];

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

htuch commented Apr 3, 2020

@snowp it probably makes sense to document. We can't use PGV though, you'd need something like CEL to express cross-field constraints which we don't have today.

@adisuissa can you ad a comment to https://github.com/envoyproxy/envoy/blob/master/api/envoy/api/v2/endpoint/endpoint_components.proto#L93 and https://github.com/envoyproxy/envoy/blob/master/api/envoy/api/v2/endpoint/endpoint_components.proto#L121 to make this explicit in the API docs? Thanks.

@adisuissa
Copy link
Contributor Author

@snowp it probably makes sense to document. We can't use PGV though, you'd need something like CEL to express cross-field constraints which we don't have today.

@adisuissa can you ad a comment to https://github.com/envoyproxy/envoy/blob/master/api/envoy/api/v2/endpoint/endpoint_components.proto#L93 and https://github.com/envoyproxy/envoy/blob/master/api/envoy/api/v2/endpoint/endpoint_components.proto#L121 to make this explicit in the API docs? Thanks.

Sure.
I'm assuming it also needs to be added to v3 (probably will be handled by proto_format), but if I'm wrong please correct me.

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

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

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

🐱

Caused by: #10578 was synchronize by adisuissa.

see: more, trace.

@htuch
Copy link
Member

htuch commented Apr 5, 2020

/lgtm api

@repokitteh-read-only repokitteh-read-only bot removed the api label Apr 5, 2020
@adisuissa
Copy link
Contributor Author

/retest

@repokitteh-read-only
Copy link

🔨 rebuilding ci/circleci: coverage (failed build)

🐱

Caused by: a #10578 (comment) was created by @adisuissa.

see: more, trace.

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

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

@snowp snowp left a comment

Choose a reason for hiding this comment

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

LGTM. @htuch this needs another API sign off

Copy link
Member

@mattklein123 mattklein123 left a comment

Choose a reason for hiding this comment

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

Please merge master so the v4alpha changes propagate.

…20200330

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

Please merge master so the v4alpha changes propagate.

merged latest master.

@repokitteh-read-only repokitteh-read-only bot removed the api label Apr 8, 2020
@mattklein123 mattklein123 merged commit e1df07e into envoyproxy:master Apr 8, 2020
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