From 479e7288a394bdffc8aa5612afa7c1aaf5245015 Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Fri, 18 Oct 2024 17:24:50 -0600 Subject: [PATCH 1/2] new(tests) Add stack overflow by rule check to JUMPF Just like CALLF, JUMPF has a stack overflow by rule check that tests were not tripping. Signed-off-by: Danno Ferrin --- .../eip7692_eof_v1/eip6206_jumpf/helpers.py | 2 + .../eip6206_jumpf/test_jumpf_execution.py | 47 ++++++++++++++----- 2 files changed, 38 insertions(+), 11 deletions(-) diff --git a/tests/osaka/eip7692_eof_v1/eip6206_jumpf/helpers.py b/tests/osaka/eip7692_eof_v1/eip6206_jumpf/helpers.py index 056278eca87..1f17950e5c7 100644 --- a/tests/osaka/eip7692_eof_v1/eip6206_jumpf/helpers.py +++ b/tests/osaka/eip7692_eof_v1/eip6206_jumpf/helpers.py @@ -8,6 +8,8 @@ next(_slot) # don't use slot 0 slot_code_worked = next(_slot) slot_last_slot = next(_slot) +slot_stack_canary = next(_slot) """Storage values for common testing fields""" value_code_worked = 0x2015 +value_canary_written = 0xDEADB12D diff --git a/tests/osaka/eip7692_eof_v1/eip6206_jumpf/test_jumpf_execution.py b/tests/osaka/eip7692_eof_v1/eip6206_jumpf/test_jumpf_execution.py index 611d528c621..d61477854ba 100644 --- a/tests/osaka/eip7692_eof_v1/eip6206_jumpf/test_jumpf_execution.py +++ b/tests/osaka/eip7692_eof_v1/eip6206_jumpf/test_jumpf_execution.py @@ -10,7 +10,7 @@ from ethereum_test_tools.vm.opcode import Opcodes as Op from .. import EOF_FORK_NAME -from .helpers import slot_code_worked, value_code_worked +from .helpers import slot_code_worked, slot_stack_canary, value_canary_written, value_code_worked REFERENCE_SPEC_GIT_PATH = "EIPS/eip-6206.md" REFERENCE_SPEC_VERSION = "2f365ea0cd58faa6e26013ea77ce6d538175f7d0" @@ -235,39 +235,64 @@ def test_jumpf_stack_size_1024_at_push( ) +@pytest.mark.parametrize( + ("stack_height", "failure"), + ( + pytest.param(1021, False, id="no_overflow"), + pytest.param(1022, True, id="rule_overflow"), + pytest.param(1023, True, id="execution_overflow"), + ), +) def test_jumpf_stack_overflow( + stack_height: int, + failure: bool, eof_state_test: EOFStateTestFiller, ): - """Test stack overflowing 1024 items in JUMPF target function""" + """ + Test stack overflowing 1024 items in JUMPF target function + + `no_overflow` - the stack does not overflow at JUMPF call, executes to end + `rule_overflow` - reserved stack overflows, but execution would not overflow + `execution_overflow` - execution would overflow (but still blocked by reserved stack rule) + """ eof_state_test( data=Container( sections=[ Section.Code( - code=Op.PUSH0 * 1023 + code=Op.PUSH0 * stack_height + Op.CALLF[1] - + Op.POP * 1023 + + Op.POP * stack_height + Op.SSTORE(slot_code_worked, value_code_worked) + Op.RETURN(0, 0), - max_stack_height=1023, + max_stack_height=stack_height, ), Section.Code( - # Stack has 1023 items + # Stack has stack_height items Op.JUMPF[2], code_inputs=0, code_outputs=0, max_stack_height=0, ), Section.Code( - Op.PUSH0 + Op.PUSH0 + - # Runtime stack overflow - Op.POP + Op.POP + Op.RETF, + Op.CALLDATALOAD(0) + + Op.ISZERO + + Op.RJUMPI[6] + + Op.PUSH0 * 3 + + Op.POP * 3 + + Op.SSTORE(slot_stack_canary, value_canary_written) + + Op.RETF, code_inputs=0, code_outputs=0, - max_stack_height=2, + max_stack_height=3, ), ], ), - container_post=Account(storage={slot_code_worked: 0}), + container_post=Account( + storage={ + slot_code_worked: 0 if failure else value_code_worked, + slot_stack_canary: 0 if failure else value_canary_written, + } + ), ) From 5662537ffb28af7705757fc63de85ecf9ff47281 Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Thu, 24 Oct 2024 21:37:12 -0600 Subject: [PATCH 2/2] update comments Signed-off-by: Danno Ferrin --- .../eip7692_eof_v1/eip6206_jumpf/test_jumpf_execution.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/osaka/eip7692_eof_v1/eip6206_jumpf/test_jumpf_execution.py b/tests/osaka/eip7692_eof_v1/eip6206_jumpf/test_jumpf_execution.py index d61477854ba..9970081ef95 100644 --- a/tests/osaka/eip7692_eof_v1/eip6206_jumpf/test_jumpf_execution.py +++ b/tests/osaka/eip7692_eof_v1/eip6206_jumpf/test_jumpf_execution.py @@ -249,10 +249,12 @@ def test_jumpf_stack_overflow( eof_state_test: EOFStateTestFiller, ): """ - Test stack overflowing 1024 items in JUMPF target function + Test rule #2 in execution semantics, where we make sure we have enough stack to guarantee + safe execution (the "reserved stack rule") max possible stack will not exceed 1024. But some + executions may not overflow the stack, so we need to ensure the rule is checked. `no_overflow` - the stack does not overflow at JUMPF call, executes to end - `rule_overflow` - reserved stack overflows, but execution would not overflow + `rule_overflow` - reserved stack rule triggers, but execution would not overflow if allowed `execution_overflow` - execution would overflow (but still blocked by reserved stack rule) """ eof_state_test(