Skip to content

Commit

Permalink
Merge pull request #569 from CosmWasm/add-handle_vm_panic
Browse files Browse the repository at this point in the history
Improve panic handling code and communication
  • Loading branch information
chipshort authored Nov 5, 2024
2 parents 2b79acd + b785826 commit 0d7a848
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 11 deletions.
19 changes: 10 additions & 9 deletions libwasmvm/src/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use serde::Serialize;
use crate::api::GoApi;
use crate::args::{CACHE_ARG, CHECKSUM_ARG, CONFIG_ARG, WASM_ARG};
use crate::error::{handle_c_error_binary, handle_c_error_default, handle_c_error_ptr, Error};
use crate::handle_vm_panic::handle_vm_panic;
use crate::memory::{ByteSliceView, UnmanagedVector};
use crate::querier::GoQuerier;
use crate::storage::GoStorage;
Expand All @@ -31,7 +32,7 @@ pub extern "C" fn init_cache(
error_msg: Option<&mut UnmanagedVector>,
) -> *mut cache_t {
let r = catch_unwind(|| do_init_cache(config)).unwrap_or_else(|err| {
eprintln!("Panic in do_init_cache: {err:?}");
handle_vm_panic("do_init_cache", err);
Err(Error::panic())
});
handle_c_error_ptr(r, error_msg) as *mut cache_t
Expand All @@ -56,7 +57,7 @@ pub extern "C" fn save_wasm(
let r = match to_cache(cache) {
Some(c) => catch_unwind(AssertUnwindSafe(move || do_save_wasm(c, wasm, unchecked)))
.unwrap_or_else(|err| {
eprintln!("Panic in do_save_wasm: {err:?}");
handle_vm_panic("do_save_wasm", err);
Err(Error::panic())
}),
None => Err(Error::unset_arg(CACHE_ARG)),
Expand Down Expand Up @@ -88,7 +89,7 @@ pub extern "C" fn remove_wasm(
let r = match to_cache(cache) {
Some(c) => catch_unwind(AssertUnwindSafe(move || do_remove_wasm(c, checksum)))
.unwrap_or_else(|err| {
eprintln!("Panic in do_remove_wasm: {err:?}");
handle_vm_panic("do_remove_wasm", err);
Err(Error::panic())
}),
None => Err(Error::unset_arg(CACHE_ARG)),
Expand Down Expand Up @@ -117,7 +118,7 @@ pub extern "C" fn load_wasm(
let r = match to_cache(cache) {
Some(c) => catch_unwind(AssertUnwindSafe(move || do_load_wasm(c, checksum)))
.unwrap_or_else(|err| {
eprintln!("Panic in do_load_wasm: {err:?}");
handle_vm_panic("do_load_wasm", err);
Err(Error::panic())
}),
None => Err(Error::unset_arg(CACHE_ARG)),
Expand Down Expand Up @@ -147,7 +148,7 @@ pub extern "C" fn pin(
let r = match to_cache(cache) {
Some(c) => {
catch_unwind(AssertUnwindSafe(move || do_pin(c, checksum))).unwrap_or_else(|err| {
eprintln!("Panic in do_pin: {err:?}");
handle_vm_panic("do_pin", err);
Err(Error::panic())
})
}
Expand Down Expand Up @@ -177,7 +178,7 @@ pub extern "C" fn unpin(
let r = match to_cache(cache) {
Some(c) => {
catch_unwind(AssertUnwindSafe(move || do_unpin(c, checksum))).unwrap_or_else(|err| {
eprintln!("Panic in do_unpin: {err:?}");
handle_vm_panic("do_unpin", err);
Err(Error::panic())
})
}
Expand Down Expand Up @@ -285,7 +286,7 @@ pub extern "C" fn analyze_code(
let r = match to_cache(cache) {
Some(c) => catch_unwind(AssertUnwindSafe(move || do_analyze_code(c, checksum)))
.unwrap_or_else(|err| {
eprintln!("Panic in do_analyze_code: {err:?}");
handle_vm_panic("do_analyze_code", err);
Err(Error::panic())
}),
None => Err(Error::unset_arg(CACHE_ARG)),
Expand Down Expand Up @@ -363,7 +364,7 @@ pub extern "C" fn get_metrics(
let r = match to_cache(cache) {
Some(c) => {
catch_unwind(AssertUnwindSafe(move || do_get_metrics(c))).unwrap_or_else(|err| {
eprintln!("Panic in do_get_metrics: {err:?}");
handle_vm_panic("do_get_metrics", err);
Err(Error::panic())
})
}
Expand Down Expand Up @@ -418,7 +419,7 @@ pub extern "C" fn get_pinned_metrics(
let r = match to_cache(cache) {
Some(c) => {
catch_unwind(AssertUnwindSafe(move || do_get_pinned_metrics(c))).unwrap_or_else(|err| {
eprintln!("Panic in do_get_pinned_metrics: {err:?}");
handle_vm_panic("do_get_pinned_metrics", err);
Err(Error::panic())
})
}
Expand Down
5 changes: 3 additions & 2 deletions libwasmvm/src/calls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use crate::args::{ARG1, ARG2, ARG3, CACHE_ARG, CHECKSUM_ARG, GAS_REPORT_ARG};
use crate::cache::{cache_t, to_cache};
use crate::db::Db;
use crate::error::{handle_c_error_binary, Error};
use crate::handle_vm_panic::handle_vm_panic;
use crate::memory::{ByteSliceView, UnmanagedVector};
use crate::querier::GoQuerier;
use crate::storage::GoStorage;
Expand Down Expand Up @@ -528,7 +529,7 @@ fn call_2_args(
)
}))
.unwrap_or_else(|err| {
eprintln!("Panic in do_call_2_args: {err:?}");
handle_vm_panic("do_call_2_args", err);
Err(Error::panic())
}),
None => Err(Error::unset_arg(CACHE_ARG)),
Expand Down Expand Up @@ -622,7 +623,7 @@ fn call_3_args(
)
}))
.unwrap_or_else(|err| {
eprintln!("Panic in do_call_3_args: {err:?}");
handle_vm_panic("do_call_3_args", err);
Err(Error::panic())
}),
None => Err(Error::unset_arg(CACHE_ARG)),
Expand Down
34 changes: 34 additions & 0 deletions libwasmvm/src/handle_vm_panic.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
use std::any::Any;

/// A function to process cases in which the VM panics.
///
/// We want to provide as much debug information as possible
/// as those cases are not expated to happen during healthy operations.
pub fn handle_vm_panic(what: &str, err: Box<dyn Any + Send + 'static>) {
eprintln!("Panic in {what}:");
eprintln!("{err:?}"); // Does not show useful information, see https://users.rust-lang.org/t/return-value-from-catch-unwind-is-a-useless-any/89134/6
eprintln!(
"This indicates a panic in during the operations of libwasmvm/cosmwasm-vm.
Such panics must not happen and are considered bugs. If you see this in any real-world or
close-to-real-world usage of wasmvm, please consider filing a security report,
no matter if it can be abused or not:
(https://github.com/CosmWasm/advisories/blob/main/SECURITY.md#reporting-a-vulnerability).
Thank you for your help keeping CosmWasm safe and secure 💚"
);
}

#[cfg(test)]
mod tests {
use super::*;

use std::panic::catch_unwind;

#[test]
fn handle_vm_panic_works() {
fn nice_try() {
panic!("oh no!");
}
let err = catch_unwind(nice_try).unwrap_err();
handle_vm_panic("nice_try", err);
}
}
1 change: 1 addition & 0 deletions libwasmvm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ mod db;
mod error;
mod gas_meter;
mod gas_report;
mod handle_vm_panic;
mod iterator;
mod memory;
mod querier;
Expand Down

0 comments on commit 0d7a848

Please sign in to comment.