From 5efac70a74225f4aba6c1272635261a753551af8 Mon Sep 17 00:00:00 2001 From: jianguo Date: Tue, 16 Jan 2024 00:12:58 +0800 Subject: [PATCH 1/2] update --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e97a398474..f9ef94c19e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ and this project adheres to ## [Unreleased] -## [1.0.1] - 2023-04-17 +## [1.0.1] - 2023-04-17 ### Fixed From 7594feb0c2ce0b9148e64839a1583cb06ad2d2f3 Mon Sep 17 00:00:00 2001 From: jianguo Date: Tue, 16 Jan 2024 00:41:37 +0800 Subject: [PATCH 2/2] update --- packages/vm/src/compatibility.rs | 53 ++++++++++++++++++++ packages/vm/src/modules/file_system_cache.rs | 11 ++-- 2 files changed, 61 insertions(+), 3 deletions(-) diff --git a/packages/vm/src/compatibility.rs b/packages/vm/src/compatibility.rs index 01775a7b1d..3b55e664c9 100644 --- a/packages/vm/src/compatibility.rs +++ b/packages/vm/src/compatibility.rs @@ -1,3 +1,4 @@ +use parity_wasm::elements::Type; use parity_wasm::elements::{External, ImportEntry, Module}; use std::collections::BTreeSet; use std::collections::HashSet; @@ -50,6 +51,12 @@ const SUPPORTED_INTERFACE_VERSIONS: &[&str] = &[ const MEMORY_LIMIT: u32 = 512; // in pages +const MAX_FUNCTIONS: usize = 10000; + +const MAX_FUNCTION_PARAMS: usize = 50; + +const MAX_FUNCTION_RESULTS: usize = 1; + /// Checks if the data is valid wasm and compatibility with the CosmWasm API (imports and exports) pub fn check_wasm(wasm_code: &[u8], supported_features: &HashSet) -> VmResult<()> { let module = deserialize_wasm(wasm_code)?; @@ -58,6 +65,52 @@ pub fn check_wasm(wasm_code: &[u8], supported_features: &HashSet) -> VmR check_wasm_exports(&module)?; check_wasm_imports(&module, SUPPORTED_IMPORTS)?; check_wasm_features(&module, supported_features)?; + check_wasm_functions(&module)?; + Ok(()) +} + +fn check_wasm_functions(module: &Module) -> VmResult<()> { + let functions = module + .function_section() + .map(|fs| fs.entries()) + .unwrap_or_default(); + + if functions.len() > MAX_FUNCTIONS { + return Err(VmError::static_validation_err(format!( + "Wasm contract contains more than {MAX_FUNCTIONS} functions" + ))); + } + + let types = module + .type_section() + .map(|ts| ts.types()) + .unwrap_or_default(); + + let max_func_params = types + .iter() + .map(|t| match t { + Type::Function(f) => f.params().len(), + }) + .max() + .unwrap_or_default(); + let max_func_results = types + .iter() + .map(|t| match t { + Type::Function(f) => f.results().len(), + }) + .max() + .unwrap_or_default(); + + if max_func_params > MAX_FUNCTION_PARAMS { + return Err(VmError::static_validation_err(format!( + "Wasm contract contains function with more than {MAX_FUNCTION_PARAMS} parameters" + ))); + } + if max_func_results > MAX_FUNCTION_RESULTS { + return Err(VmError::static_validation_err(format!( + "Wasm contract contains function with more than {MAX_FUNCTION_RESULTS} results" + ))); + } Ok(()) } diff --git a/packages/vm/src/modules/file_system_cache.rs b/packages/vm/src/modules/file_system_cache.rs index 2bc87965eb..c8b4b322fa 100644 --- a/packages/vm/src/modules/file_system_cache.rs +++ b/packages/vm/src/modules/file_system_cache.rs @@ -1,5 +1,7 @@ use std::fs; use std::io; +use std::panic::catch_unwind; +use std::panic::AssertUnwindSafe; use std::path::PathBuf; use wasmer::{DeserializeError, Module, Store}; @@ -119,9 +121,12 @@ impl FileSystemCache { .map_err(|e| VmError::cache_err(format!("Error creating directory: {}", e)))?; let filename = checksum.to_hex(); let path = modules_dir.join(filename); - module - .serialize_to_file(path) - .map_err(|e| VmError::cache_err(format!("Error writing module to disk: {}", e)))?; + catch_unwind(AssertUnwindSafe(|| { + module + .serialize_to_file(&path) + .map_err(|e| VmError::cache_err(format!("Error writing module to disk: {e}"))) + })) + .map_err(|_| VmError::cache_err("Could not write module to disk"))??; Ok(()) }