-
Notifications
You must be signed in to change notification settings - Fork 88
Description
When a host function defined using linker.FuncWrap() with a *Caller parameter panics, wasmtime-go crashes with a nil pointer dereference in func.go instead of properly propagating the panic.
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x2 addr=0x28 pc=0x...]
goroutine 1 [running]:
github.com/bytecodealliance/wasmtime-go/v37.enterWasm(...)
github.com/bytecodealliance/wasmtime-go/[email protected]/func.go:539
Or in some cases, the panic occurs at line 539 but with the original panic message rather than being properly handled.
The code attempts to access data.lastPanic where data is returned from getDataInStore(store):
if data.lastPanic != nil {
lastPanic := data.lastPanic // line 537
data.lastPanic = nil
panic(lastPanic) // line 539
}When a panic occurs in a FuncWrap function with a *Caller parameter, getDataInStore(store) returns nil, causing a nil pointer dereference when attempting to access data.lastPanic.
Simple host function definition that reproduces the bug:
linker := wasmtime.NewLinker(engine)
err := linker.FuncWrap("env", "host_panic", func(caller *wasmtime.Caller) int32
{
panic("some error") // This panic triggers the bug
})WAT:
(module
;; Import host function that will panic
(import "env" "host_panic" (func $host_panic (result i32)))
;; Export a test function that calls the host function
(func (export "test") (result i32)
;; Call the host function that will panic
call $host_panic
)
)This bug makes it impossible to use Go's standard panic/recover mechanism for error handling in host functions when using wasmtime-go with the *Caller parameter.
Maybe the code should check if data is nil before dereferencing:
data := getDataInStore(store)
if data != nil && data.lastPanic != nil {
lastPanic := data.lastPanic
data.lastPanic = nil
panic(lastPanic)
}