Skip to content

Commit d083842

Browse files
authored
new(tests): EOF - EIP-6206: Add stack overflow by rule check to JUMPF (ethereum#902)
* 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 <[email protected]> * update comments Signed-off-by: Danno Ferrin <[email protected]> --------- Signed-off-by: Danno Ferrin <[email protected]>
1 parent b8d5496 commit d083842

File tree

2 files changed

+40
-11
lines changed

2 files changed

+40
-11
lines changed

osaka/eip7692_eof_v1/eip6206_jumpf/helpers.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
next(_slot) # don't use slot 0
99
slot_code_worked = next(_slot)
1010
slot_last_slot = next(_slot)
11+
slot_stack_canary = next(_slot)
1112

1213
"""Storage values for common testing fields"""
1314
value_code_worked = 0x2015
15+
value_canary_written = 0xDEADB12D

osaka/eip7692_eof_v1/eip6206_jumpf/test_jumpf_execution.py

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from ethereum_test_tools.vm.opcode import Opcodes as Op
1111

1212
from .. import EOF_FORK_NAME
13-
from .helpers import slot_code_worked, value_code_worked
13+
from .helpers import slot_code_worked, slot_stack_canary, value_canary_written, value_code_worked
1414

1515
REFERENCE_SPEC_GIT_PATH = "EIPS/eip-6206.md"
1616
REFERENCE_SPEC_VERSION = "2f365ea0cd58faa6e26013ea77ce6d538175f7d0"
@@ -235,39 +235,66 @@ def test_jumpf_stack_size_1024_at_push(
235235
)
236236

237237

238+
@pytest.mark.parametrize(
239+
("stack_height", "failure"),
240+
(
241+
pytest.param(1021, False, id="no_overflow"),
242+
pytest.param(1022, True, id="rule_overflow"),
243+
pytest.param(1023, True, id="execution_overflow"),
244+
),
245+
)
238246
def test_jumpf_stack_overflow(
247+
stack_height: int,
248+
failure: bool,
239249
eof_state_test: EOFStateTestFiller,
240250
):
241-
"""Test stack overflowing 1024 items in JUMPF target function"""
251+
"""
252+
Test rule #2 in execution semantics, where we make sure we have enough stack to guarantee
253+
safe execution (the "reserved stack rule") max possible stack will not exceed 1024. But some
254+
executions may not overflow the stack, so we need to ensure the rule is checked.
255+
256+
`no_overflow` - the stack does not overflow at JUMPF call, executes to end
257+
`rule_overflow` - reserved stack rule triggers, but execution would not overflow if allowed
258+
`execution_overflow` - execution would overflow (but still blocked by reserved stack rule)
259+
"""
242260
eof_state_test(
243261
data=Container(
244262
sections=[
245263
Section.Code(
246-
code=Op.PUSH0 * 1023
264+
code=Op.PUSH0 * stack_height
247265
+ Op.CALLF[1]
248-
+ Op.POP * 1023
266+
+ Op.POP * stack_height
249267
+ Op.SSTORE(slot_code_worked, value_code_worked)
250268
+ Op.RETURN(0, 0),
251-
max_stack_height=1023,
269+
max_stack_height=stack_height,
252270
),
253271
Section.Code(
254-
# Stack has 1023 items
272+
# Stack has stack_height items
255273
Op.JUMPF[2],
256274
code_inputs=0,
257275
code_outputs=0,
258276
max_stack_height=0,
259277
),
260278
Section.Code(
261-
Op.PUSH0 + Op.PUSH0 +
262-
# Runtime stack overflow
263-
Op.POP + Op.POP + Op.RETF,
279+
Op.CALLDATALOAD(0)
280+
+ Op.ISZERO
281+
+ Op.RJUMPI[6]
282+
+ Op.PUSH0 * 3
283+
+ Op.POP * 3
284+
+ Op.SSTORE(slot_stack_canary, value_canary_written)
285+
+ Op.RETF,
264286
code_inputs=0,
265287
code_outputs=0,
266-
max_stack_height=2,
288+
max_stack_height=3,
267289
),
268290
],
269291
),
270-
container_post=Account(storage={slot_code_worked: 0}),
292+
container_post=Account(
293+
storage={
294+
slot_code_worked: 0 if failure else value_code_worked,
295+
slot_stack_canary: 0 if failure else value_canary_written,
296+
}
297+
),
271298
)
272299

273300

0 commit comments

Comments
 (0)