Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add checks for API and Querier pointers #485

Merged
merged 1 commit into from
Dec 1, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions internal/api/lib.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,8 @@ func Instantiate(
defer runtime.KeepAlive(msg)
var pinner runtime.Pinner
pinner.Pin(gasMeter)
checkAndPinAPI(api, pinner)
checkAndPinQuerier(querier, pinner)
defer pinner.Unpin()

callID := startCall()
Expand Down Expand Up @@ -226,6 +228,8 @@ func Execute(
defer runtime.KeepAlive(msg)
var pinner runtime.Pinner
pinner.Pin(gasMeter)
checkAndPinAPI(api, pinner)
checkAndPinQuerier(querier, pinner)
defer pinner.Unpin()

callID := startCall()
Expand Down Expand Up @@ -266,6 +270,8 @@ func Migrate(
defer runtime.KeepAlive(msg)
var pinner runtime.Pinner
pinner.Pin(gasMeter)
checkAndPinAPI(api, pinner)
checkAndPinQuerier(querier, pinner)
defer pinner.Unpin()

callID := startCall()
Expand Down Expand Up @@ -306,6 +312,8 @@ func Sudo(
defer runtime.KeepAlive(msg)
var pinner runtime.Pinner
pinner.Pin(gasMeter)
checkAndPinAPI(api, pinner)
checkAndPinQuerier(querier, pinner)
defer pinner.Unpin()

callID := startCall()
Expand Down Expand Up @@ -346,6 +354,8 @@ func Reply(
defer runtime.KeepAlive(reply)
var pinner runtime.Pinner
pinner.Pin(gasMeter)
checkAndPinAPI(api, pinner)
checkAndPinQuerier(querier, pinner)
defer pinner.Unpin()

callID := startCall()
Expand Down Expand Up @@ -386,6 +396,8 @@ func Query(
defer runtime.KeepAlive(msg)
var pinner runtime.Pinner
pinner.Pin(gasMeter)
checkAndPinAPI(api, pinner)
checkAndPinQuerier(querier, pinner)
defer pinner.Unpin()

callID := startCall()
Expand Down Expand Up @@ -426,6 +438,8 @@ func IBCChannelOpen(
defer runtime.KeepAlive(msg)
var pinner runtime.Pinner
pinner.Pin(gasMeter)
checkAndPinAPI(api, pinner)
checkAndPinQuerier(querier, pinner)
defer pinner.Unpin()

callID := startCall()
Expand Down Expand Up @@ -466,6 +480,8 @@ func IBCChannelConnect(
defer runtime.KeepAlive(msg)
var pinner runtime.Pinner
pinner.Pin(gasMeter)
checkAndPinAPI(api, pinner)
checkAndPinQuerier(querier, pinner)
defer pinner.Unpin()

callID := startCall()
Expand Down Expand Up @@ -506,6 +522,8 @@ func IBCChannelClose(
defer runtime.KeepAlive(msg)
var pinner runtime.Pinner
pinner.Pin(gasMeter)
checkAndPinAPI(api, pinner)
checkAndPinQuerier(querier, pinner)
defer pinner.Unpin()

callID := startCall()
Expand Down Expand Up @@ -546,6 +564,8 @@ func IBCPacketReceive(
defer runtime.KeepAlive(packet)
var pinner runtime.Pinner
pinner.Pin(gasMeter)
checkAndPinAPI(api, pinner)
checkAndPinQuerier(querier, pinner)
defer pinner.Unpin()

callID := startCall()
Expand Down Expand Up @@ -586,6 +606,8 @@ func IBCPacketAck(
defer runtime.KeepAlive(ack)
var pinner runtime.Pinner
pinner.Pin(gasMeter)
checkAndPinAPI(api, pinner)
checkAndPinQuerier(querier, pinner)
defer pinner.Unpin()

callID := startCall()
Expand Down Expand Up @@ -626,6 +648,8 @@ func IBCPacketTimeout(
defer runtime.KeepAlive(packet)
var pinner runtime.Pinner
pinner.Pin(gasMeter)
checkAndPinAPI(api, pinner)
checkAndPinQuerier(querier, pinner)
defer pinner.Unpin()

callID := startCall()
Expand Down Expand Up @@ -668,3 +692,35 @@ func errorWithMessage(err error, b C.UnmanagedVector) error {
}
return fmt.Errorf("%s", string(msg))
}

// checkAndPinAPI checks and pins the API and relevant pointers inside of it.
// All errors will result in panics as they indicate misuse of the wasmvm API and are not expected
// to be caused by user data.
func checkAndPinAPI(api *types.GoAPI, pinner runtime.Pinner) {
if api == nil {
panic("API must not be nil. If you don't want to provide API functionality, please create an instance that returns an error on every call to HumanAddress() and CanonicalAddress().")
}

// func cHumanAddress assumes this is set
if api.HumanAddress == nil {
panic("HumanAddress in API must not be nil. If you don't want to provide API functionality, please create an instance that returns an error on every call to HumanAddress() and CanonicalAddress().")
}

// func cCanonicalAddress assums this is set
if api.CanonicalAddress == nil {
panic("CanonicalAddress in API must not be nil. If you don't want to provide API functionality, please create an instance that returns an error on every call to HumanAddress() and CanonicalAddress().")
}

pinner.Pin(api) // this pointer is used in Rust (`state` in `C.GoApi`) and must not change
}

// checkAndPinQuerier checks and pins the querier.
// All errors will result in panics as they indicate misuse of the wasmvm API and are not expected
// to be caused by user data.
func checkAndPinQuerier(querier *Querier, pinner runtime.Pinner) {
if querier == nil {
panic("Querier must not be nil. If you don't want to provide querier functionality, please create an instance that returns an error on every call to Query().")
}

pinner.Pin(querier) // this pointer is used in Rust (`state` in `C.GoQuerier`) and must not change
}