Skip to content

Panic in FuncWrap with *Caller causes nil pointer dereference #255

@alterstep

Description

@alterstep

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)
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions