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

Limit length of error messages #1086

Merged
merged 1 commit into from
Aug 25, 2022
Merged
Show file tree
Hide file tree
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
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()))
}