From ee9ef1fbc4da0f606af2db028890654cfbf3f6d6 Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Mon, 3 Feb 2020 10:10:01 +0100 Subject: [PATCH] eth/tracers: fix panics occurring for invalid params in js-tracers --- eth/tracers/tracer.go | 13 +++++++++++-- eth/tracers/tracer_test.go | 19 ++++++------------- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/eth/tracers/tracer.go b/eth/tracers/tracer.go index 63d38ed32d..a74ed51e1a 100644 --- a/eth/tracers/tracer.go +++ b/eth/tracers/tracer.go @@ -93,6 +93,15 @@ type memoryWrapper struct { // slice returns the requested range of memory as a byte slice. func (mw *memoryWrapper) slice(begin, end int64) []byte { + if end == begin { + return []byte{} + } + if end < begin || begin < 0 { + // TODO(karalabe): We can't js-throw from Go inside duktape inside Go. The Go + // runtime goes belly up https://github.com/golang/go/issues/15639. + log.Warn("Tracer accessed out of bound memory", "offset", begin, "end", end) + return nil + } if mw.memory.Len() < int(end) { // TODO(karalabe): We can't js-throw from Go inside duktape inside Go. The Go // runtime goes belly up https://github.com/golang/go/issues/15639. @@ -104,7 +113,7 @@ func (mw *memoryWrapper) slice(begin, end int64) []byte { // getUint returns the 32 bytes at the specified address interpreted as a uint. func (mw *memoryWrapper) getUint(addr int64) *big.Int { - if mw.memory.Len() < int(addr)+32 { + if mw.memory.Len() < int(addr)+32 || addr < 0 { // TODO(karalabe): We can't js-throw from Go inside duktape inside Go. The Go // runtime goes belly up https://github.com/golang/go/issues/15639. log.Warn("Tracer accessed out of bound memory", "available", mw.memory.Len(), "offset", addr, "size", 32) @@ -147,7 +156,7 @@ type stackWrapper struct { // peek returns the nth-from-the-top element of the stack. func (sw *stackWrapper) peek(idx int) *big.Int { - if len(sw.stack.Data()) <= idx { + if len(sw.stack.Data()) <= idx || idx < 0 { // TODO(karalabe): We can't js-throw from Go inside duktape inside Go. The Go // runtime goes belly up https://github.com/golang/go/issues/15639. log.Warn("Tracer accessed out of bound stack", "size", len(sw.stack.Data()), "index", idx) diff --git a/eth/tracers/tracer_test.go b/eth/tracers/tracer_test.go index 4f1b982bf8..0f52370675 100644 --- a/eth/tracers/tracer_test.go +++ b/eth/tracers/tracer_test.go @@ -63,44 +63,37 @@ func runTrace(tracer *Tracer) (json.RawMessage, error) { return tracer.GetResult() } +// TestRegressionPanicSlice tests that we don't panic on bad arguments to memory access func TestRegressionPanicSlice(t *testing.T) { tracer, err := New("{depths: [], step: function(log) { this.depths.push(log.memory.slice(-1,-2)); }, fault: function() {}, result: function() { return this.depths; }}") if err != nil { t.Fatal(err) } - - ret, err := runTrace(tracer) - if err != nil { + if _, err = runTrace(tracer); err != nil { t.Fatal(err) } - t.Logf("Got result %s", string(ret)) } +// TestRegressionPanicSlice tests that we don't panic on bad arguments to stack peeks func TestRegressionPanicPeek(t *testing.T) { tracer, err := New("{depths: [], step: function(log) { this.depths.push(log.stack.peek(-1)); }, fault: function() {}, result: function() { return this.depths; }}") if err != nil { t.Fatal(err) } - - ret, err := runTrace(tracer) - if err != nil { + if _, err = runTrace(tracer); err != nil { t.Fatal(err) } - t.Logf("Expected return value to be [0,1,2], got %s", string(ret)) } - +// TestRegressionPanicSlice tests that we don't panic on bad arguments to memory getUint func TestRegressionPanicGetUint(t *testing.T) { tracer, err := New("{ depths: [], step: function(log, db) { this.depths.push(log.memory.getUint(-64));}, fault: function() {}, result: function() { return this.depths; }}") if err != nil { t.Fatal(err) } - - ret, err := runTrace(tracer) - if err != nil { + if _, err = runTrace(tracer); err != nil { t.Fatal(err) } - t.Logf("Expected return value to be [0,1,2], got %s", string(ret)) } func TestTracing(t *testing.T) {