Skip to content

Commit 0d7a848

Browse files
authored
Merge pull request #569 from CosmWasm/add-handle_vm_panic
Improve panic handling code and communication
2 parents 2b79acd + b785826 commit 0d7a848

File tree

4 files changed

+48
-11
lines changed

4 files changed

+48
-11
lines changed

libwasmvm/src/cache.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use serde::Serialize;
99
use crate::api::GoApi;
1010
use crate::args::{CACHE_ARG, CHECKSUM_ARG, CONFIG_ARG, WASM_ARG};
1111
use crate::error::{handle_c_error_binary, handle_c_error_default, handle_c_error_ptr, Error};
12+
use crate::handle_vm_panic::handle_vm_panic;
1213
use crate::memory::{ByteSliceView, UnmanagedVector};
1314
use crate::querier::GoQuerier;
1415
use crate::storage::GoStorage;
@@ -31,7 +32,7 @@ pub extern "C" fn init_cache(
3132
error_msg: Option<&mut UnmanagedVector>,
3233
) -> *mut cache_t {
3334
let r = catch_unwind(|| do_init_cache(config)).unwrap_or_else(|err| {
34-
eprintln!("Panic in do_init_cache: {err:?}");
35+
handle_vm_panic("do_init_cache", err);
3536
Err(Error::panic())
3637
});
3738
handle_c_error_ptr(r, error_msg) as *mut cache_t
@@ -56,7 +57,7 @@ pub extern "C" fn save_wasm(
5657
let r = match to_cache(cache) {
5758
Some(c) => catch_unwind(AssertUnwindSafe(move || do_save_wasm(c, wasm, unchecked)))
5859
.unwrap_or_else(|err| {
59-
eprintln!("Panic in do_save_wasm: {err:?}");
60+
handle_vm_panic("do_save_wasm", err);
6061
Err(Error::panic())
6162
}),
6263
None => Err(Error::unset_arg(CACHE_ARG)),
@@ -88,7 +89,7 @@ pub extern "C" fn remove_wasm(
8889
let r = match to_cache(cache) {
8990
Some(c) => catch_unwind(AssertUnwindSafe(move || do_remove_wasm(c, checksum)))
9091
.unwrap_or_else(|err| {
91-
eprintln!("Panic in do_remove_wasm: {err:?}");
92+
handle_vm_panic("do_remove_wasm", err);
9293
Err(Error::panic())
9394
}),
9495
None => Err(Error::unset_arg(CACHE_ARG)),
@@ -117,7 +118,7 @@ pub extern "C" fn load_wasm(
117118
let r = match to_cache(cache) {
118119
Some(c) => catch_unwind(AssertUnwindSafe(move || do_load_wasm(c, checksum)))
119120
.unwrap_or_else(|err| {
120-
eprintln!("Panic in do_load_wasm: {err:?}");
121+
handle_vm_panic("do_load_wasm", err);
121122
Err(Error::panic())
122123
}),
123124
None => Err(Error::unset_arg(CACHE_ARG)),
@@ -147,7 +148,7 @@ pub extern "C" fn pin(
147148
let r = match to_cache(cache) {
148149
Some(c) => {
149150
catch_unwind(AssertUnwindSafe(move || do_pin(c, checksum))).unwrap_or_else(|err| {
150-
eprintln!("Panic in do_pin: {err:?}");
151+
handle_vm_panic("do_pin", err);
151152
Err(Error::panic())
152153
})
153154
}
@@ -177,7 +178,7 @@ pub extern "C" fn unpin(
177178
let r = match to_cache(cache) {
178179
Some(c) => {
179180
catch_unwind(AssertUnwindSafe(move || do_unpin(c, checksum))).unwrap_or_else(|err| {
180-
eprintln!("Panic in do_unpin: {err:?}");
181+
handle_vm_panic("do_unpin", err);
181182
Err(Error::panic())
182183
})
183184
}
@@ -285,7 +286,7 @@ pub extern "C" fn analyze_code(
285286
let r = match to_cache(cache) {
286287
Some(c) => catch_unwind(AssertUnwindSafe(move || do_analyze_code(c, checksum)))
287288
.unwrap_or_else(|err| {
288-
eprintln!("Panic in do_analyze_code: {err:?}");
289+
handle_vm_panic("do_analyze_code", err);
289290
Err(Error::panic())
290291
}),
291292
None => Err(Error::unset_arg(CACHE_ARG)),
@@ -363,7 +364,7 @@ pub extern "C" fn get_metrics(
363364
let r = match to_cache(cache) {
364365
Some(c) => {
365366
catch_unwind(AssertUnwindSafe(move || do_get_metrics(c))).unwrap_or_else(|err| {
366-
eprintln!("Panic in do_get_metrics: {err:?}");
367+
handle_vm_panic("do_get_metrics", err);
367368
Err(Error::panic())
368369
})
369370
}
@@ -418,7 +419,7 @@ pub extern "C" fn get_pinned_metrics(
418419
let r = match to_cache(cache) {
419420
Some(c) => {
420421
catch_unwind(AssertUnwindSafe(move || do_get_pinned_metrics(c))).unwrap_or_else(|err| {
421-
eprintln!("Panic in do_get_pinned_metrics: {err:?}");
422+
handle_vm_panic("do_get_pinned_metrics", err);
422423
Err(Error::panic())
423424
})
424425
}

libwasmvm/src/calls.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use crate::args::{ARG1, ARG2, ARG3, CACHE_ARG, CHECKSUM_ARG, GAS_REPORT_ARG};
1919
use crate::cache::{cache_t, to_cache};
2020
use crate::db::Db;
2121
use crate::error::{handle_c_error_binary, Error};
22+
use crate::handle_vm_panic::handle_vm_panic;
2223
use crate::memory::{ByteSliceView, UnmanagedVector};
2324
use crate::querier::GoQuerier;
2425
use crate::storage::GoStorage;
@@ -528,7 +529,7 @@ fn call_2_args(
528529
)
529530
}))
530531
.unwrap_or_else(|err| {
531-
eprintln!("Panic in do_call_2_args: {err:?}");
532+
handle_vm_panic("do_call_2_args", err);
532533
Err(Error::panic())
533534
}),
534535
None => Err(Error::unset_arg(CACHE_ARG)),
@@ -622,7 +623,7 @@ fn call_3_args(
622623
)
623624
}))
624625
.unwrap_or_else(|err| {
625-
eprintln!("Panic in do_call_3_args: {err:?}");
626+
handle_vm_panic("do_call_3_args", err);
626627
Err(Error::panic())
627628
}),
628629
None => Err(Error::unset_arg(CACHE_ARG)),

libwasmvm/src/handle_vm_panic.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
use std::any::Any;
2+
3+
/// A function to process cases in which the VM panics.
4+
///
5+
/// We want to provide as much debug information as possible
6+
/// as those cases are not expated to happen during healthy operations.
7+
pub fn handle_vm_panic(what: &str, err: Box<dyn Any + Send + 'static>) {
8+
eprintln!("Panic in {what}:");
9+
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
10+
eprintln!(
11+
"This indicates a panic in during the operations of libwasmvm/cosmwasm-vm.
12+
Such panics must not happen and are considered bugs. If you see this in any real-world or
13+
close-to-real-world usage of wasmvm, please consider filing a security report,
14+
no matter if it can be abused or not:
15+
(https://github.com/CosmWasm/advisories/blob/main/SECURITY.md#reporting-a-vulnerability).
16+
Thank you for your help keeping CosmWasm safe and secure 💚"
17+
);
18+
}
19+
20+
#[cfg(test)]
21+
mod tests {
22+
use super::*;
23+
24+
use std::panic::catch_unwind;
25+
26+
#[test]
27+
fn handle_vm_panic_works() {
28+
fn nice_try() {
29+
panic!("oh no!");
30+
}
31+
let err = catch_unwind(nice_try).unwrap_err();
32+
handle_vm_panic("nice_try", err);
33+
}
34+
}

libwasmvm/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ mod db;
99
mod error;
1010
mod gas_meter;
1111
mod gas_report;
12+
mod handle_vm_panic;
1213
mod iterator;
1314
mod memory;
1415
mod querier;

0 commit comments

Comments
 (0)