Skip to content
This repository was archived by the owner on May 11, 2020. It is now read-only.

Conversation

@vibhavp
Copy link
Collaborator

@vibhavp vibhavp commented Dec 22, 2017

In Disassemble, the function uses the integer immediate for
call_indirect as an index into the global index space, while it should
be an index into the Type Section of the module. This causes it to
reference an incorrect function, which would cause stack underflows
later on. This CL fixes that.

Also, fix the select operator decreasing the stack height by 3 instead
of 2.

(Fixes #49)


This change is Reviewable

In Disassemble, the function uses the integer immediate for
call_indirect as an index into the global index space, while it should
be an index into the Type Section of the module. This causes  it to
reference an incorrect function, which would cause stack underflows
later on. This CL fixes that.

Also, fix the select operator decreasing the stack height by 3 instead
of 2.

(Fixes go-interpreter#49)
@Spriithy
Copy link
Contributor

:lgtm:


Review status: 0 of 1 files reviewed at latest revision, all discussions resolved, some commit checks failed.


Comments from Reviewable

@sbinet
Copy link
Contributor

sbinet commented Dec 22, 2017

it would seem travis fails in the same way than what was reported in #49:

panic: runtime error: slice bounds out of range [recovered]
	panic: runtime error: slice bounds out of range
goroutine 43 [running]:
testing.tRunner.func1(0xc4200e02d0)
	/home/travis/.gimme/versions/go1.9.2.linux.amd64/src/testing/testing.go:711 +0x2d2
panic(0x58dea0, 0x6a97b0)
	/home/travis/.gimme/versions/go1.9.2.linux.amd64/src/runtime/panic.go:491 +0x283
github.com/go-interpreter/wagon/exec.(*VM).execCode(0xc420481600, 0xc42045c000, 0x57, 0xad, 0x6d3018, 0x0, 0x0, 0x3, 0x1, 0x1, ...)
	/home/travis/gopath/src/github.com/go-interpreter/wagon/exec/vm.go:345 +0x70e
github.com/go-interpreter/wagon/exec.(*VM).ExecCode(0xc420481600, 0x1f, 0xc420104ad8, 0x1, 0x1, 0x1, 0xc4201049f0, 0x0, 0x0)
	/home/travis/gopath/src/github.com/go-interpreter/wagon/exec/vm.go:262 +0x1d5
github.com/go-interpreter/wagon/exec_test.runTest(0xc420020540, 0x5d, 0xc42002ec00, 0x2e, 0x3f, 0x69b480, 0xc4200e02d0)
	/home/travis/gopath/src/github.com/go-interpreter/wagon/exec/exec_test.go:310 +0x524
github.com/go-interpreter/wagon/exec_test.testModules.func1(0xc4200e02d0)
	/home/travis/gopath/src/github.com/go-interpreter/wagon/exec/exec_test.go:361 +0x126
testing.tRunner(0xc4200e02d0, 0xc42021a780)
	/home/travis/.gimme/versions/go1.9.2.linux.amd64/src/testing/testing.go:746 +0xd0
created by testing.(*T).Run
	/home/travis/.gimme/versions/go1.9.2.linux.amd64/src/testing/testing.go:789 +0x2de
FAIL	github.com/go-interpreter/wagon/exec	0.291s

@sbinet
Copy link
Contributor

sbinet commented Dec 22, 2017

with a bit of print-foo:

vm.go:349: ==> place=2 len=1, end=-1
vm.go:350: error: runtime error: slice bounds out of range
panic: runtime error: slice bounds out of range [recovered]
	panic: runtime error: slice bounds out of range [recovered]
	panic: runtime error: slice bounds out of range

goroutine 60 [running]:
testing.tRunner.func1(0xc4205161e0)
	/usr/lib/go/src/testing/testing.go:711 +0x2d2
panic(0x58dea0, 0x6a77b0)
	/usr/lib/go/src/runtime/panic.go:491 +0x283
github.com/go-interpreter/wagon/exec.(*VM).execCode.func1(0x2, 0xc420410000, 0xffffffffffffffff)
	/home/binet/work/gsoc/src/github.com/go-interpreter/wagon/exec/vm.go:351 +0x1eb
panic(0x58dea0, 0x6a77b0)
	/usr/lib/go/src/runtime/panic.go:491 +0x283
github.com/go-interpreter/wagon/exec.(*VM).execCode(0xc420410000, 0xc42001c0b0, 0x57, 0xad, 0x6d1018, 0x0, 0x0, 0x3, 0x1, 0x1, ...)
	/home/binet/work/gsoc/src/github.com/go-interpreter/wagon/exec/vm.go:354 +0x783
github.com/go-interpreter/wagon/exec.(*VM).ExecCode(0xc420410000, 0x1f, 0xc420434a10, 0x1, 0x1, 0x1, 0xc4204348e8, 0x0, 0x0)
	/home/binet/work/gsoc/src/github.com/go-interpreter/wagon/exec/vm.go:263 +0x1d5
github.com/go-interpreter/wagon/exec_test.runTest(0xc420374000, 0x5f, 0xc420249300, 0x2e, 0x3f, 0x699480, 0xc4205161e0)
	/home/binet/work/gsoc/src/github.com/go-interpreter/wagon/exec/exec_test.go:310 +0x524
github.com/go-interpreter/wagon/exec_test.testModules.func1(0xc4205161e0)
	/home/binet/work/gsoc/src/github.com/go-interpreter/wagon/exec/exec_test.go:361 +0x126
testing.tRunner(0xc4205161e0, 0xc4202465a0)
	/usr/lib/go/src/testing/testing.go:746 +0xd0
created by testing.(*T).Run
	/usr/lib/go/src/testing/testing.go:789 +0x2de
FAIL	github.com/go-interpreter/wagon/exec	0.135s

with:

diff --git a/exec/vm.go b/exec/vm.go
index cb1ba36..5d7ca42 100644
--- a/exec/vm.go
+++ b/exec/vm.go
@@ -9,6 +9,7 @@ import (
        "encoding/binary"
        "errors"
        "fmt"
+       "log"
        "math"
 
        "github.com/go-interpreter/wagon/disasm"
@@ -342,6 +343,14 @@ outer:
                case compile.OpDiscardPreserveTop:
                        top := vm.ctx.stack[len(vm.ctx.stack)-1]
                        place := vm.fetchInt64()
+                       end := len(vm.ctx.stack) - int(place)
+                       defer func() {
+                               if e := recover(); e != nil {
+                                       log.Printf("==> place=%d len=%d, end=%d", place, len(vm.ctx.stack), end)
+                                       log.Printf("error: %v", e)
+                                       panic(e)
+                               }
+                       }()
                        vm.ctx.stack = vm.ctx.stack[:len(vm.ctx.stack)-int(place)]
                        vm.pushUint64(top)
                default:

@bkeroackdsc
Copy link
Contributor

That error looks the same as the one fixed by #52

vibhavp added 6 commits April 5, 2018 15:00
Replace with BlockInfo.PairIndex four indices:

* IfElseIndex - For an if instruction, this is the index to the
  corresponding else instruction.

* ElseIfIndex - For an else instruction, this is the index to the
  corresponding if instruction.

* EndIndex - For a block/loop/if/else instruction, this is the index
  to the corresponding end instruction.

* BlockStartIndex - For an end instruction, this is the index to the
  instruction that started the block itself.
This ensures the stack length always starts with 0.
@sbinet
Copy link
Contributor

sbinet commented Apr 5, 2018

first pass looks ok, but, could you add a test?
e.g. something extracted from #49 (comment) perhaps?

@sbinet
Copy link
Contributor

sbinet commented Apr 9, 2018

Reviewed 3 of 4 files at r2, 4 of 5 files at r3.
Review status: 7 of 8 files reviewed at latest revision, all discussions resolved.


disasm/disasm.go, line 462 at r3 (raw file):

	}

	for _, instr := range disas.Code {

perhaps guard this possibly expansive loop with a test on whether we are in verbose/debug mode or not ?


Comments from Reviewable

@vibhavp
Copy link
Collaborator Author

vibhavp commented Apr 9, 2018

Review status: 6 of 8 files reviewed at latest revision, 1 unresolved discussion.


disasm/disasm.go, line 462 at r3 (raw file):

Previously, sbinet (Sebastien Binet) wrote…

perhaps guard this possibly expansive loop with a test on whether we are in verbose/debug mode or not ?

Done.


Comments from Reviewable

@sbinet
Copy link
Contributor

sbinet commented Apr 9, 2018

:lgtm:


Reviewed 2 of 2 files at r4.
Review status: all files reviewed at latest revision, all discussions resolved.


Comments from Reviewable

@sbinet sbinet merged commit d73568a into go-interpreter:master Apr 9, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Stack Underflow on valid wasm file

4 participants