Skip to content

Commit

Permalink
Merge pull request #54 from MariusVanDerWijden/eof-fuzzing-2
Browse files Browse the repository at this point in the history
Eof fuzzing 2
  • Loading branch information
MariusVanDerWijden authored Sep 8, 2024
2 parents 48e2124 + df20601 commit 4be7308
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 9 deletions.
6 changes: 3 additions & 3 deletions cmd/eofdump/eofparser.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ func ExecuteTest(src []byte) (int, int, error) {
return 0, 0, err
}
passed, total := 0, 0
for _, tests := range testsByName {
for testsName, tests := range testsByName {
for name, tt := range tests.Vectors {
for fork, r := range tt.Results {
total++
Expand All @@ -181,11 +181,11 @@ func ExecuteTest(src []byte) (int, int, error) {
err = err2
}
if r.Result && err != nil {
fmt.Fprintf(os.Stderr, "%s, %s: expected success, got %v\n", name, fork, err)
fmt.Fprintf(os.Stderr, "%s %s, %s: expected success, got %v\n", testsName, name, fork, err)
continue
}
if !r.Result && err == nil {
fmt.Fprintf(os.Stderr, "%s, %s: expected error %s, got %v\n", name, fork, r.Exception, err)
fmt.Fprintf(os.Stderr, "%s %s, %s: expected error %s, got %v\n", testsName, name, fork, r.Exception, err)
continue
}
/*
Expand Down
3 changes: 3 additions & 0 deletions core/vm/eof.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,9 @@ func (c *Container) unmarshalSubContainer(b []byte, isInitcode bool, topLevel bo
if kind != kindContainer {
panic("somethings wrong")
}
if len(containerSizes) == 0 {
return fmt.Errorf("%w: total container count must not be zero", ErrInvalidContainerSectionSize)
}
offset = offset + 2 + 2*len(containerSizes) + 1
}

Expand Down
1 change: 1 addition & 0 deletions core/vm/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ var (
ErrInvalidEOFInitcode = errors.New("invalid eof initcode")
ErrNonceUintOverflow = errors.New("nonce uint64 overflow")
ErrInvalidNumberOfOutputs = errors.New("invalid number of outputs")
ErrInvalidNonReturningFlag = errors.New("Invalid non-returning flag, bad RETF")

// errStopToken is an internal token indicating interpreter loop termination,
// never returned to outside callers.
Expand Down
6 changes: 2 additions & 4 deletions core/vm/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,8 @@ func validateCode(code []byte, section int, container *Container, jt *JumpTable,
if arg >= len(container.Types) {
return nil, fmt.Errorf("%w: arg %d, last %d, pos %d", ErrInvalidSectionArgument, arg, len(container.Types), i)
}
// TODO check if that is actually a problem
// JUMPF operand must point to a code section with equal or fewer number of outputs as the section in which it resides, or to a section with 0x80 as outputs (non-returning)
if container.Types[arg].Output > container.Types[section].Output {
return nil, fmt.Errorf("%w: arg %d, last %d, pos %d", ErrInvalidSectionArgument, arg, len(container.Types), i)
if container.Types[arg].Output != 0x80 && container.Types[arg].Output > container.Types[section].Output {
return nil, fmt.Errorf("%w: arg %d, last %d, pos %d", ErrInvalidNumberOfOutputs, arg, len(container.Types), i)
}
visitedCode[arg] = struct{}{}
case op == DATALOADN:
Expand Down
16 changes: 14 additions & 2 deletions core/vm/validate_linear.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ func validateControlFlow2(code []byte, section int, metadata []*FunctionMetadata
// set the initial stack bounds
setBounds(0, int(metadata[section].Input), int(metadata[section].Input))

qualifiedExit := false
for pos := 0; pos < len(code); pos++ {
op := OpCode(code[pos])
currentBounds := stackBounds[pos]
Expand Down Expand Up @@ -62,9 +63,14 @@ func validateControlFlow2(code []byte, section int, metadata []*FunctionMetadata
if currentBounds.max != currentBounds.min {
return 0, fmt.Errorf("%w: max %d, min %d, at pos %d", ErrInvalidNumberOfOutputs, currentBounds.max, currentBounds.min, pos)
}
if have, want := int(metadata[section].Output), currentBounds.min; have != want {
have := int(metadata[section].Output)
if have >= maxOutputItems {
return 0, fmt.Errorf("%w: at pos %d", ErrInvalidNonReturningFlag, pos)
}
if want := currentBounds.min; have != want {
return 0, fmt.Errorf("%w: have %d, want %d, at pos %d", ErrInvalidOutputs, have, want, pos)
}
qualifiedExit = true
case JUMPF:
arg, _ := parseUint16(code[pos+1:])
newSection := metadata[arg]
Expand All @@ -83,6 +89,7 @@ func validateControlFlow2(code []byte, section int, metadata []*FunctionMetadata
return 0, fmt.Errorf("%w: at pos %d", ErrInvalidNumberOfOutputs, pos)
}
}
qualifiedExit = qualifiedExit || newSection.Output < maxOutputItems
case DUPN:
arg := int(code[pos+1]) + 1
if want, have := arg, currentBounds.min; want > have {
Expand Down Expand Up @@ -175,12 +182,14 @@ func validateControlFlow2(code []byte, section int, metadata []*FunctionMetadata
// target reached via backwards jump
nextBounds, ok := stackBounds[nextPC]
if !ok {
fmt.Print("2")
return 0, ErrInvalidBackwardJump
}
if currentStackMax != nextBounds.max {
return 0, fmt.Errorf("%w want %d as current max got %d at pos %d,", ErrInvalidBackwardJump, currentStackMax, nextBounds.max, pos)
}
if currentStackMin != nextBounds.min {
return 0, fmt.Errorf("%w want %d as current min got %d at pos %d,", ErrInvalidBackwardJump, currentStackMin, nextBounds.min, pos)
}
}
}
}
Expand All @@ -192,6 +201,9 @@ func validateControlFlow2(code []byte, section int, metadata []*FunctionMetadata
}

}
if qualifiedExit != (metadata[section].Output < maxOutputItems) {
return 0, fmt.Errorf("%w no RETF or qualified JUMPF", ErrInvalidNonReturningFlag)
}
if maxStackHeight >= int(params.StackLimit) {
return 0, ErrStackOverflow{maxStackHeight, int(params.StackLimit)}
}
Expand Down

0 comments on commit 4be7308

Please sign in to comment.