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

Disallow unreachable code sections #721

Merged
merged 1 commit into from
Jan 22, 2024
Merged

Conversation

hugo-dc
Copy link
Member

@hugo-dc hugo-dc commented Oct 23, 2023

This PR disallows EOF unreachable code sections.

Pending:

  • Add new unit tests specific for unreachable code sections

@hugo-dc hugo-dc requested a review from gumb0 October 23, 2023 09:20
@codecov
Copy link

codecov bot commented Oct 23, 2023

Codecov Report

Attention: 3 lines in your changes are missing coverage. Please review.

Comparison is base (b74b9db) 97.90% compared to head (b9ee992) 97.91%.

Additional details and impacted files
@@           Coverage Diff           @@
##           master     #721   +/-   ##
=======================================
  Coverage   97.90%   97.91%           
=======================================
  Files         110      110           
  Lines       10573    10644   +71     
=======================================
+ Hits        10352    10422   +70     
- Misses        221      222    +1     
Flag Coverage Δ
blockchaintests 59.92% <0.00%> (-0.32%) ⬇️
statetests 62.22% <85.71%> (+0.05%) ⬆️
statetests-silkpre 25.83% <0.00%> (-0.17%) ⬇️
unittests 95.88% <96.93%> (+<0.01%) ⬆️

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 100.00% <100.00%> (ø)
test/unittests/eof_test.cpp 94.11% <85.71%> (+0.78%) ⬆️
lib/evmone/eof.cpp 83.75% <81.81%> (+0.10%) ⬆️

@gumb0 gumb0 requested review from pdobacz and rodiazet October 23, 2023 16:27
lib/evmone/eof.cpp Outdated Show resolved Hide resolved
lib/evmone/eof.cpp Outdated Show resolved Hide resolved
@gumb0
Copy link
Member

gumb0 commented Nov 28, 2023

Please rebase and take into account sections targeted by JUMPF.

@gumb0
Copy link
Member

gumb0 commented Nov 28, 2023

Also please add a validation unit test with unreachable sections error.

lib/evmone/eof.cpp Outdated Show resolved Hide resolved
@chfast chfast added the EOF label Jan 3, 2024
@hugo-dc hugo-dc assigned hugo-dc and unassigned hugo-dc Jan 8, 2024
@hugo-dc hugo-dc force-pushed the unreachable-code-sections branch from ff5e515 to db57f5e Compare January 10, 2024 07:06
test/unittests/eof_test.cpp Outdated Show resolved Hide resolved
@gumb0
Copy link
Member

gumb0 commented Jan 10, 2024

Note also you can now build an EOF bytecode with multiple section using bytecode.hpp utility, like here:

const bytecode code =
eof_bytecode(1023 * push(1) + OP_CALLF + "0001" + 1021 * OP_POP + OP_RETURN, 1023)
.code(push(1) + OP_CALLF + "0002" + OP_POP + OP_RETF, 0, 0, 1)
.code(push(1) + OP_POP + OP_RETF, 0, 0, 1);

@hugo-dc hugo-dc force-pushed the unreachable-code-sections branch 2 times, most recently from 170d99c to 727c180 Compare January 10, 2024 21:50
@hugo-dc hugo-dc marked this pull request as ready for review January 12, 2024 00:06
@hugo-dc
Copy link
Member Author

hugo-dc commented Jan 12, 2024

Note also you can now build an EOF bytecode with multiple section using bytecode.hpp utility, like here:

...

In new tests I'm using that approach:

const auto code = eof_bytecode(bytecode{OP_CALLF} + "0001" + OP_STOP, 0)
.code(bytecode{"5B"} + OP_RETF, 0, 0, 0)
.code(bytecode{"FE"}, 0, 0x80, 0);

However, in some other parts, I'm generating the code "manually" in order to generate many code sections where each section calls the next one:

EXPECT_EQ(
validate_eof(from_spaced_hex("EF00 01 010400 020100" + section_size_256 + "040000 00" +
section_types_256 + code_sections_256_err_001)
.value()),

Not sure if there is a way to do something like that by using the bytecode.hpp utility.

lib/evmone/eof.cpp Outdated Show resolved Hide resolved
test/unittests/eof_validation_test.cpp Outdated Show resolved Hide resolved
std::string section_types_256;
for (int i = 0; i < 256; ++i)
{
section_size_256 += "0003";
Copy link
Member

Choose a reason for hiding this comment

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

I found a more concise way of making these sequences, I think I'll make a separate PR with it.

Copy link
Member

@gumb0 gumb0 Jan 17, 2024

Choose a reason for hiding this comment

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

I did it in #796, please rebase now and use similar approach here.

code_sections_1024 += "5B5B00";

const auto valid = "EF0001 011000" + bytecode{"020400"} + 0x400 * bytecode{"0003"} +
"040000 00" + 0x400 * bytecode{"00800000"} + code_sections_1024;
EXPECT_EQ(validate_eof(valid), EOFValidationError::success);

const auto invalid = "EF0001 011002" + bytecode{"020401"} + 0x401 * bytecode{"0001"} +
Copy link
Member

Choose a reason for hiding this comment

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

It would make ssense to use code_sections_1024 in invalid case, too, just adding one more after them.

Copy link
Member Author

Choose a reason for hiding this comment

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

I added another variable code_sections_1025 in order that section 1024 is calling section 1025 (so we don't have unreachable code sections).

Copy link
Member

@chfast chfast left a comment

Choose a reason for hiding this comment

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

Issues I reported were fixed.

@hugo-dc hugo-dc force-pushed the unreachable-code-sections branch from 4807f11 to 6bd75ff Compare January 17, 2024 18:51
std::string code_sections_256_err_254 = "E50001E50002";
std::string cs_calling_next;
for (int i = 0; i < 252; ++i)
cs_calling_next += "E5" + hex(big_endian(static_cast<uint16_t>(i + 1)));
Copy link
Member

Choose a reason for hiding this comment

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

Not sure this does what you intended, maybe loop index is wrong, e.g. code_sections_256_err_254 seems to end up with a sequence jumpf{1} jumpf{2} jumpf{1} jumpf{2} jumpf{3} ...
I think intention was to have jumpf{1} jumpf{2} jumpf{3} jumpf{4} ...

Also, if you want to use bytecode here, it should be possible with something like:

auto code_sections_256_err_001 = eof_bytecode(bytecode{JUMPF} + "0001").code(bytecode{JUMPF} + "0002", 0, 0x80, 0);
for (int i = 2; i < 254; ++i)
  code_sections_256_err_001.code(bytecode{JUMPF} + big_endian(static_cast<uint16_t>(i + 1)), 0, 0x80, 0); 

(Also would be nice to have helpers in bytecode.hpp for callf / jumpf to not write bytecode{JUMPF} every time, but that's probably better for separate PR)

Copy link
Member Author

Choose a reason for hiding this comment

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

There was an error in the loop indices, it is fixed and it is now using bytecode.

@hugo-dc hugo-dc force-pushed the unreachable-code-sections branch 2 times, most recently from c3eef35 to 89434de Compare January 17, 2024 22:18
@gumb0
Copy link
Member

gumb0 commented Jan 18, 2024

Looks fine to me now, could you squash the commits?

@hugo-dc hugo-dc force-pushed the unreachable-code-sections branch from 89434de to da47d23 Compare January 18, 2024 20:56
@hugo-dc
Copy link
Member Author

hugo-dc commented Jan 18, 2024

Looks fine to me now, could you squash the commits?

Commits squashed

@gumb0 gumb0 force-pushed the unreachable-code-sections branch from da47d23 to b9ee992 Compare January 22, 2024 14:37
@gumb0 gumb0 merged commit 83e7a32 into master Jan 22, 2024
24 of 25 checks passed
@gumb0 gumb0 deleted the unreachable-code-sections branch January 22, 2024 14:55
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.

4 participants