diff --git a/crates/wasmparser/src/limits.rs b/crates/wasmparser/src/limits.rs index 118629f894..157c3b236f 100644 --- a/crates/wasmparser/src/limits.rs +++ b/crates/wasmparser/src/limits.rs @@ -17,6 +17,8 @@ // The following limits are imposed by wasmparser on WebAssembly modules. // The limits are agreed upon with other engines for consistency. +// +// See https://webassembly.github.io/spec/js-api/#limits for details. pub const MAX_WASM_TYPES: usize = 1_000_000; pub const MAX_WASM_SUPERTYPES: usize = 1; pub const MAX_WASM_FUNCTIONS: usize = 1_000_000; @@ -26,7 +28,7 @@ pub const MAX_WASM_GLOBALS: usize = 1_000_000; pub const MAX_WASM_ELEMENT_SEGMENTS: usize = 100_000; pub const MAX_WASM_DATA_SEGMENTS: usize = 100_000; pub const MAX_WASM_STRING_SIZE: usize = 100_000; -pub const MAX_WASM_FUNCTION_SIZE: usize = 128 * 1024; +pub const MAX_WASM_FUNCTION_SIZE: usize = 7_654_321; pub const MAX_WASM_FUNCTION_LOCALS: u32 = 50000; pub const MAX_WASM_FUNCTION_PARAMS: usize = 1000; pub const MAX_WASM_FUNCTION_RETURNS: usize = 1000; diff --git a/crates/wasmparser/src/validator.rs b/crates/wasmparser/src/validator.rs index a5c345e895..c675ece0f0 100644 --- a/crates/wasmparser/src/validator.rs +++ b/crates/wasmparser/src/validator.rs @@ -1006,6 +1006,14 @@ impl Validator { ) -> Result> { let offset = body.range().start; self.state.ensure_module("code", offset)?; + check_max( + 0, + u32::try_from(body.range().len()) + .expect("usize already validated to u32 during section-length decoding"), + MAX_WASM_FUNCTION_SIZE, + "function body size", + offset, + )?; let state = self.module.as_mut().unwrap(); diff --git a/crates/wasmparser/tests/big-module.rs b/crates/wasmparser/tests/big-module.rs index 9064eba88b..3ad2c90286 100644 --- a/crates/wasmparser/tests/big-module.rs +++ b/crates/wasmparser/tests/big-module.rs @@ -32,3 +32,31 @@ fn big_type_indices() { .validate_all(&wasm) .unwrap(); } + +#[test] +fn big_function_body() { + let mut module = Module::new(); + + let mut types = TypeSection::new(); + types.ty().function([], []); + module.section(&types); + let mut funcs = FunctionSection::new(); + funcs.function(0); + module.section(&funcs); + + let mut code = CodeSection::new(); + let mut body = Function::new([]); + // Function body larger than the 7_654_321-byte implementation + // limit. + for _ in 0..8_000_000 { + body.instructions().unreachable(); + } + body.instructions().end(); + code.function(&body); + module.section(&code); + + let wasm = module.finish(); + + let result = wasmparser::Validator::default().validate_all(&wasm); + assert!(result.is_err()); +}