bytecodealliance / bytecodealliance/wasmtime-go

Panic in FuncWrap with *Caller causes nil pointer dereference

Open
#255 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Go
Stars
913
Forks
100
Avg merge
10m
Merged PRs (30d)
1

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/v37@v37.0.0/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)`:

```go
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:

```go
linker := wasmtime.NewLinker(engine)
err := linker.FuncWrap("env", "host_panic", func(caller *wasmtime.Caller) int32
{
panic("some error") // This panic triggers the bug
})
```

WAT:

```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:

```go
data := getDataInStore(store)
if data != nil && data.lastPanic != nil {
lastPanic := data.lastPanic
data.lastPanic = nil
panic(lastPanic)
}
```

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.