Skip to content

Commit

Permalink
Limit length of error messages
Browse files Browse the repository at this point in the history
  • Loading branch information
Cashmaney committed Aug 23, 2022
1 parent 2977d7d commit 1db91a8
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 70 deletions.
108 changes: 40 additions & 68 deletions cosmwasm/packages/sgx-vm/src/errors/vm_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ use crate::ffi::FfiError;

use super::EnclaveError;

const MAX_ERR_LEN: usize = 4096;

#[derive(Debug, Snafu)]
#[non_exhaustive]
pub enum VmError {
Expand Down Expand Up @@ -105,11 +107,11 @@ pub enum VmError {
#[allow(unused)]
impl VmError {
pub(crate) fn cache_err<S: Into<String>>(msg: S) -> Self {
CacheErr { msg: msg.into() }.build()
CacheErr { msg: &Self::truncate_input(msg) }.build()
}

pub(crate) fn compile_err<S: Into<String>>(msg: S) -> Self {
CompileErr { msg: msg.into() }.build()
CompileErr { msg: &Self::truncate_input(msg) }.build()
}

pub(crate) fn conversion_err<S: Into<String>, T: Into<String>, U: Into<String>>(
Expand All @@ -118,19 +120,19 @@ impl VmError {
input: U,
) -> Self {
ConversionErr {
from_type: from_type.into(),
to_type: to_type.into(),
input: input.into(),
from_type: &Self::truncate_input(from_type),
to_type: &Self::truncate_input(to_type),
input: &Self::truncate_input(input),
}
.build()
}

pub(crate) fn generic_err<S: Into<String>>(msg: S) -> Self {
GenericErr { msg: msg.into() }.build()
GenericErr { msg: &Self::truncate_input(msg) }.build()
}

pub(crate) fn instantiation_err<S: Into<String>>(msg: S) -> Self {
InstantiationErr { msg: msg.into() }.build()
InstantiationErr { msg: &Self::truncate_input(msg) }.build()
}

pub(crate) fn integrity_err() -> Self {
Expand All @@ -142,36 +144,45 @@ impl VmError {
IteratorDoesNotExist { id: iterator_id }.build()
}

pub(crate) fn parse_err<T: Into<String>, M: Display>(target: T, msg: M) -> Self {
pub(crate) fn parse_err<T: Into<String>, M: Into<String>>(target: T, msg: M) -> Self {
ParseErr {
target: target.into(),
msg: msg.to_string(),
target: &Self::truncate_input(target),
msg: &Self::truncate_input(msg),
}
.build()
}

pub(crate) fn serialize_err<S: Into<String>, M: Display>(source: S, msg: M) -> Self {
pub(crate) fn serialize_err<S: Into<String>, M: Into<String>>(source: S, msg: M) -> Self {
SerializeErr {
source: source.into(),
msg: msg.to_string(),
source: &Self::truncate_input(source),
msg: &Self::truncate_input(msg),
}
.build()
}

pub(crate) fn resolve_err<S: Into<String>>(msg: S) -> Self {
ResolveErr { msg: msg.into() }.build()
ResolveErr { msg: &Self::truncate_input(msg) }.build()
}

pub(crate) fn runtime_err<S: Into<String>>(msg: S) -> Self {
RuntimeErr { msg: msg.into() }.build()
RuntimeErr { msg: &Self::truncate_input(msg) }.build()
}

pub(crate) fn static_validation_err<S: Into<String>>(msg: S) -> Self {
StaticValidationErr { msg: msg.into() }.build()
StaticValidationErr { msg: &Self::truncate_input(msg) }.build()
}

pub(crate) fn uninitialized_context_data<S: Into<String>>(kind: S) -> Self {
UninitializedContextData { kind: kind.into() }.build()
UninitializedContextData { kind: &Self::truncate_input(kind) }.build()
}

// this is not super ideal, as we don't want super long strings to be copied and moved around
// but it'll at least limit the shit that gets thrown on-chain
fn truncate_input<S: Into<String>>(msg: S) -> String {
let mut s: String = msg.into();

s.truncate(MAX_ERR_LEN);
s
}

pub(crate) fn write_access_denied() -> Self {
Expand All @@ -196,57 +207,6 @@ impl From<FfiError> for VmError {
}
}

/*
impl From<wasmer_runtime_core::cache::Error> for VmError {
fn from(original: wasmer_runtime_core::cache::Error) -> Self {
VmError::cache_err(format!("Wasmer cache error: {:?}", original))
}
}
impl From<wasmer_runtime_core::error::CompileError> for VmError {
fn from(original: wasmer_runtime_core::error::CompileError) -> Self {
VmError::compile_err(format!("Wasmer compile error: {:?}", original))
}
}
impl From<wasmer_runtime_core::error::ResolveError> for VmError {
fn from(original: wasmer_runtime_core::error::ResolveError) -> Self {
VmError::resolve_err(format!("Wasmer resolve error: {:?}", original))
}
}
impl From<wasmer_runtime_core::error::RuntimeError> for VmError {
fn from(original: wasmer_runtime_core::error::RuntimeError) -> Self {
use wasmer_runtime_core::error::{InvokeError, RuntimeError};
fn runtime_error(err: RuntimeError) -> VmError {
VmError::runtime_err(format!("Wasmer runtime error: {:?}", err))
}
match original {
// TODO: fix the issue described below:
// `InvokeError::FailedWithNoError` happens when running out of gas in singlepass v0.17
// but it's supposed to indicate bugs in Wasmer...
// https://github.com/wasmerio/wasmer/issues/1452
// https://github.com/CosmWasm/cosmwasm/issues/375
RuntimeError::InvokeError(InvokeError::FailedWithNoError) => VmError::GasDepletion,
// This variant contains the error we return from imports.
RuntimeError::User(err) => match err.downcast::<VmError>() {
Ok(err) => *err,
Err(err) => runtime_error(RuntimeError::User(err)),
},
_ => runtime_error(original),
}
}
}
impl From<InsufficientGasLeft> for VmError {
fn from(_original: InsufficientGasLeft) -> Self {
VmError::GasDepletion
}
}
*/

#[cfg(test)]
mod test {
use super::*;
Expand Down Expand Up @@ -301,6 +261,18 @@ mod test {
}
}

#[test]
fn truncation_of_error_works() {
let long_string = String::from_utf8(vec![b'X'; 4096]).unwrap();
let error = VmError::generic_err(format!("{} should not be here", long_string));
match error {
VmError::GenericErr { msg, .. } => {
assert_eq!(msg, long_string);
}
e => panic!("Unexpected error: {:?}", e),
}
}

#[test]
fn instantiation_err_works() {
let error = VmError::instantiation_err("something went wrong");
Expand Down
4 changes: 2 additions & 2 deletions cosmwasm/packages/sgx-vm/src/serde.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ pub fn from_slice<'a, T>(value: &'a [u8]) -> VmResult<T>
where
T: Deserialize<'a>,
{
serde_json::from_slice(value).map_err(|e| VmError::parse_err(type_name::<T>(), e))
serde_json::from_slice(value).map_err(|e| VmError::parse_err(type_name::<T>(), e.to_string()))
}

pub fn to_vec<T>(data: &T) -> VmResult<Vec<u8>>
where
T: Serialize + ?Sized,
{
serde_json::to_vec(data).map_err(|e| VmError::serialize_err(type_name::<T>(), e))
serde_json::to_vec(data).map_err(|e| VmError::serialize_err(type_name::<T>(), e.to_string()))
}

0 comments on commit 1db91a8

Please sign in to comment.