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

EOF: limit validated container size to MAX_INITCODE_SIZE #930

Merged
merged 4 commits into from
Jun 26, 2024

Conversation

pdobacz
Copy link
Collaborator

@pdobacz pdobacz commented Jun 17, 2024

@pdobacz pdobacz force-pushed the max-initcode-size branch from fe1e32d to 28f5f83 Compare June 17, 2024 12:09
Copy link

codecov bot commented Jun 17, 2024

Codecov Report

Attention: Patch coverage is 54.54545% with 5 lines in your changes missing coverage. Please review.

Project coverage is 94.27%. Comparing base (3cab4ca) to head (91f9a88).

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #930      +/-   ##
==========================================
- Coverage   94.30%   94.27%   -0.03%     
==========================================
  Files         142      142              
  Lines       16113    16123      +10     
==========================================
+ Hits        15195    15200       +5     
- Misses        918      923       +5     
Flag Coverage Δ
eof_execution_spec_tests ?
ethereum_tests 26.98% <27.27%> (+<0.01%) ⬆️
ethereum_tests_silkpre 18.85% <0.00%> (-0.01%) ⬇️
execution_spec_tests 17.97% <0.00%> (-0.02%) ⬇️
unittests 89.66% <54.54%> (-0.03%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files Coverage Δ
lib/evmone/eof.hpp 100.00% <ø> (ø)
test/unittests/eof_validation_test.cpp 99.33% <100.00%> (+<0.01%) ⬆️
test/unittests/eof_validation.cpp 90.83% <0.00%> (-1.54%) ⬇️
lib/evmone/eof.cpp 85.79% <50.00%> (-0.39%) ⬇️

@chfast chfast added the EOF label Jun 20, 2024
@@ -579,6 +582,10 @@ EOFValidationError validate_eof1(evmc_revision rev, bytes_view main_container) n
bytes_view bytes;
bool referenced_by_eofcreate = false;
};

if (main_container.size() > MAX_INITCODE_SIZE)
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

An interesting case come up, concerning this piece: Should this check be done here (top-level validate_eof) or in validate_header.

An expectation would be to have the logic of validate_header protected against oversized containers. It has been since creation txs moved to the public API of eof.hpp, so, in principle, it should also contain the check as one of the first.

OTOH, this would be wasteful, as we'd be repeating the check for all subcontainers, which are always smaller than top-level. Also validate_header bare is only ever called in host.cpp during the process of validating a creation tx data (to be precise - to discover the split between container and calldata) - but there it is protected by the transaction-level MAX_INITCODE_SIZE check.

Let me know if you have any thoughts on this

Copy link
Member

Choose a reason for hiding this comment

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

Does it mean the validate_header doesn't work correctly on its own?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Does it mean the validate_header doesn't work correctly on its own?

Only guaranteed for containers which have its size under the limit. In other words - checking size is outside of validate_header's responsibility.

Copy link
Member

Choose a reason for hiding this comment

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

If this is now the validate_header() precondition then add an assert in the validate_header().

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

ok, I reworked the comment and assertion in validate_header. I think this is good now, thx!

@pdobacz pdobacz force-pushed the max-initcode-size branch 2 times, most recently from f36adca to e22b44a Compare June 20, 2024 15:51
@pdobacz pdobacz marked this pull request as draft June 20, 2024 16:37
@pdobacz
Copy link
Collaborator Author

pdobacz commented Jun 20, 2024

Converted to draft b/c testing something on the CI front, needs to remove the TEMP commits before merging! EDIT: removed already

@pdobacz pdobacz force-pushed the max-initcode-size branch 2 times, most recently from 7a0ffdc to e99bc18 Compare June 24, 2024 11:47
@pdobacz pdobacz marked this pull request as ready for review June 24, 2024 12:09
@pdobacz pdobacz force-pushed the max-initcode-size branch from e99bc18 to 2ba1458 Compare June 24, 2024 12:54
@pdobacz
Copy link
Collaborator Author

pdobacz commented Jun 24, 2024

NOTE in a previous version I mistakenly added overflow checks for offsets (which accumulate section sizes). On second look, these weren't necessary, since a single check is done in validate_section_headers, which preceded the new checks. So it is just the MAX_INITCODE_SIZE requirement and check added, which prevents overflows and allows us to remove the overflow assertion (and not add new ones for other sections).

I have force pushed a version without these. Now codecov complains only about new lines with error message handling

@pdobacz pdobacz force-pushed the max-initcode-size branch from 2ba1458 to d55f69d Compare June 25, 2024 09:24
@pdobacz pdobacz requested review from chfast and gumb0 June 25, 2024 10:05
@@ -771,8 +784,7 @@ std::variant<EOF1Header, EOFValidationError> validate_header(
container_offsets.emplace_back(static_cast<uint16_t>(offset));
offset += container_size;
}
// NOTE: assertion always satisfied only as long as initcode limits apply (48K).
assert(offset <= std::numeric_limits<uint16_t>::max());
Copy link
Member

Choose a reason for hiding this comment

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

I think we should keep the assert.

Copy link
Member

Choose a reason for hiding this comment

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

This looks still removed?

Copy link
Member

Choose a reason for hiding this comment

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

I mean I would still keep it even if it's checked in validate_section_headers()

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

ah it moved up a bit and changed form, but the outcome is still the same (I think, please double check if in doubt) - the cast is safe.

Copy link
Member

Choose a reason for hiding this comment

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

assert(container.size() <= MAX_INITCODE_SIZE); checks that container size is checked outside validate_header() and validate_section_headers() check that declared containers sizes sum doesn't exceed container size, so the cast is safe, but I would still keep the assertion here (to prevent future errors in case validate_section_headers() is changed).

Also currently it's incosistent, you removed this assertion, but kept another one at line 776.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Also currently it's incosistent, you removed this assertion, but kept another one at line 776.

ouch, right, completely missed that.

OK on keeping the assertion, but I guess just one assertion at the end (the removed one) will be enough?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

like 537d394 for example

Copy link
Member

Choose a reason for hiding this comment

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

I would keep the one in code_size loop, too. If something goes wrong, it's easier to debug when it's detected early.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

okay, then let's keep all, one for each cast to uint16 (one was missing originally)

@@ -579,6 +582,10 @@ EOFValidationError validate_eof1(evmc_revision rev, bytes_view main_container) n
bytes_view bytes;
bool referenced_by_eofcreate = false;
};

if (main_container.size() > MAX_INITCODE_SIZE)
Copy link
Member

Choose a reason for hiding this comment

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

Does it mean the validate_header doesn't work correctly on its own?

@pdobacz pdobacz force-pushed the max-initcode-size branch from ec4b1f7 to 8251d34 Compare June 26, 2024 08:17
@pdobacz pdobacz self-assigned this Jun 26, 2024
@pdobacz
Copy link
Collaborator Author

pdobacz commented Jun 26, 2024

The 2 failed EEST cases are already failing for the base 1.0.4 release + evmone master, and are related to the RETURNCONTRACT/EOFCREATE rules introduced elsewhere. No objections to merge as is and fix forward @chfast (I'm already working on this)?

@pdobacz pdobacz force-pushed the max-initcode-size branch from 537d394 to 91f9a88 Compare June 26, 2024 13:51
@pdobacz pdobacz merged commit dbf8fb4 into master Jun 26, 2024
23 of 26 checks passed
@pdobacz pdobacz deleted the max-initcode-size branch June 26, 2024 14:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants