From 1db91a85faae647b7b728061b3e19b1d0e146f4d Mon Sep 17 00:00:00 2001 From: Cashmaney Date: Tue, 23 Aug 2022 15:28:37 +0300 Subject: [PATCH] Limit length of error messages --- .../packages/sgx-vm/src/errors/vm_error.rs | 108 +++++++----------- cosmwasm/packages/sgx-vm/src/serde.rs | 4 +- 2 files changed, 42 insertions(+), 70 deletions(-) diff --git a/cosmwasm/packages/sgx-vm/src/errors/vm_error.rs b/cosmwasm/packages/sgx-vm/src/errors/vm_error.rs index 7fca9f045..83410389d 100644 --- a/cosmwasm/packages/sgx-vm/src/errors/vm_error.rs +++ b/cosmwasm/packages/sgx-vm/src/errors/vm_error.rs @@ -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 { @@ -105,11 +107,11 @@ pub enum VmError { #[allow(unused)] impl VmError { pub(crate) fn cache_err>(msg: S) -> Self { - CacheErr { msg: msg.into() }.build() + CacheErr { msg: &Self::truncate_input(msg) }.build() } pub(crate) fn compile_err>(msg: S) -> Self { - CompileErr { msg: msg.into() }.build() + CompileErr { msg: &Self::truncate_input(msg) }.build() } pub(crate) fn conversion_err, T: Into, U: Into>( @@ -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>(msg: S) -> Self { - GenericErr { msg: msg.into() }.build() + GenericErr { msg: &Self::truncate_input(msg) }.build() } pub(crate) fn instantiation_err>(msg: S) -> Self { - InstantiationErr { msg: msg.into() }.build() + InstantiationErr { msg: &Self::truncate_input(msg) }.build() } pub(crate) fn integrity_err() -> Self { @@ -142,36 +144,45 @@ impl VmError { IteratorDoesNotExist { id: iterator_id }.build() } - pub(crate) fn parse_err, M: Display>(target: T, msg: M) -> Self { + pub(crate) fn parse_err, M: Into>(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, M: Display>(source: S, msg: M) -> Self { + pub(crate) fn serialize_err, M: Into>(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>(msg: S) -> Self { - ResolveErr { msg: msg.into() }.build() + ResolveErr { msg: &Self::truncate_input(msg) }.build() } pub(crate) fn runtime_err>(msg: S) -> Self { - RuntimeErr { msg: msg.into() }.build() + RuntimeErr { msg: &Self::truncate_input(msg) }.build() } pub(crate) fn static_validation_err>(msg: S) -> Self { - StaticValidationErr { msg: msg.into() }.build() + StaticValidationErr { msg: &Self::truncate_input(msg) }.build() } pub(crate) fn uninitialized_context_data>(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>(msg: S) -> String { + let mut s: String = msg.into(); + + s.truncate(MAX_ERR_LEN); + s } pub(crate) fn write_access_denied() -> Self { @@ -196,57 +207,6 @@ impl From for VmError { } } -/* -impl From for VmError { - fn from(original: wasmer_runtime_core::cache::Error) -> Self { - VmError::cache_err(format!("Wasmer cache error: {:?}", original)) - } -} - -impl From for VmError { - fn from(original: wasmer_runtime_core::error::CompileError) -> Self { - VmError::compile_err(format!("Wasmer compile error: {:?}", original)) - } -} - -impl From for VmError { - fn from(original: wasmer_runtime_core::error::ResolveError) -> Self { - VmError::resolve_err(format!("Wasmer resolve error: {:?}", original)) - } -} - -impl From 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::() { - Ok(err) => *err, - Err(err) => runtime_error(RuntimeError::User(err)), - }, - _ => runtime_error(original), - } - } -} - -impl From for VmError { - fn from(_original: InsufficientGasLeft) -> Self { - VmError::GasDepletion - } -} -*/ - #[cfg(test)] mod test { use super::*; @@ -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"); diff --git a/cosmwasm/packages/sgx-vm/src/serde.rs b/cosmwasm/packages/sgx-vm/src/serde.rs index 8e1640028..c4a00a2e0 100644 --- a/cosmwasm/packages/sgx-vm/src/serde.rs +++ b/cosmwasm/packages/sgx-vm/src/serde.rs @@ -11,12 +11,12 @@ pub fn from_slice<'a, T>(value: &'a [u8]) -> VmResult where T: Deserialize<'a>, { - serde_json::from_slice(value).map_err(|e| VmError::parse_err(type_name::(), e)) + serde_json::from_slice(value).map_err(|e| VmError::parse_err(type_name::(), e.to_string())) } pub fn to_vec(data: &T) -> VmResult> where T: Serialize + ?Sized, { - serde_json::to_vec(data).map_err(|e| VmError::serialize_err(type_name::(), e)) + serde_json::to_vec(data).map_err(|e| VmError::serialize_err(type_name::(), e.to_string())) }