Skip to content

Commit

Permalink
fix: patch CWA-2023-004 (#343)
Browse files Browse the repository at this point in the history
* fix: Add function number checks

This is a cherry-pick of 68486ce4d58847f9bb2368e689a4df3ce1f3f388

* fix: Catch panic

This is a cherry-pick of e6979a3d9822766cc0103db44c09b64b5a18e6b4

* build: Set version: 1.1.9+0.9.0

* Revert "build: Set version: 1.1.9+0.9.0"

This reverts commit 0dfb5b2.

---------

Co-authored-by: Christoph Otter <chris@confio.gmbh>
  • Loading branch information
loloicci and chipshort authored Feb 6, 2024
1 parent a7dad83 commit b947b68
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 3 deletions.
54 changes: 54 additions & 0 deletions packages/vm/src/compatibility.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use parity_wasm::elements::Type;
use parity_wasm::elements::{External, ImportEntry, Module};
use std::collections::BTreeSet;
use std::collections::HashSet;
Expand Down Expand Up @@ -51,6 +52,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], available_capabilities: &HashSet<String>) -> VmResult<()> {
let module = deserialize_wasm(wasm_code)?;
Expand All @@ -59,6 +66,8 @@ pub fn check_wasm(wasm_code: &[u8], available_capabilities: &HashSet<String>) ->
check_wasm_exports(&module)?;
check_wasm_imports(&module, SUPPORTED_IMPORTS)?;
check_wasm_capabilities(&module, available_capabilities)?;
check_wasm_functions(&module)?;

Ok(())
}

Expand Down Expand Up @@ -193,6 +202,51 @@ fn check_wasm_capabilities(
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(())
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
12 changes: 9 additions & 3 deletions packages/vm/src/modules/file_system_cache.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand Down Expand Up @@ -124,9 +126,13 @@ 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(())
}

Expand Down

0 comments on commit b947b68

Please sign in to comment.