From 547d9fc788643f76f3a68416d8cb478f2f025b4c Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 5 Nov 2021 10:53:23 -0700 Subject: [PATCH] Fix a panic with an invalid name section This commit fixes a panic which can happen on a module with an invalid name section where one of the functions named has the index `u32::MAX`. Previously Wasmtime would create a new `FuncIndex` with the indices found in the name section but the sentinel `u32::MAX` causes a panic. Cranelift otherwise limits the number of functions through `wasmparser` which has a hard limit (lower than `u32::MAX`) so this commit applies a fix of only recording function names for function indices that are actually present in the module. --- crates/environ/src/module_environ.rs | 10 +++++++ tests/misc_testsuite/empty.wast | 43 ++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/crates/environ/src/module_environ.rs b/crates/environ/src/module_environ.rs index 33de486a6967..e8f6ef0511f2 100644 --- a/crates/environ/src/module_environ.rs +++ b/crates/environ/src/module_environ.rs @@ -1277,6 +1277,11 @@ and for re-adding support for interface types you can see this issue: let mut names = f.get_map()?; for _ in 0..names.get_count() { let Naming { index, name } = names.read()?; + // Skip this naming if it's naming a function that + // doesn't actually exist. + if (index as usize) >= self.result.module.functions.len() { + continue; + } let index = FuncIndex::from_u32(index); self.result .module @@ -1305,6 +1310,11 @@ and for re-adding support for interface types you can see this issue: let mut reader = l.get_indirect_map()?; for _ in 0..reader.get_indirect_count() { let f = reader.read()?; + // Skip this naming if it's naming a function that + // doesn't actually exist. + if (f.indirect_index as usize) >= self.result.module.functions.len() { + continue; + } let mut map = f.get_map()?; for _ in 0..map.get_count() { let Naming { index, name } = map.read()?; diff --git a/tests/misc_testsuite/empty.wast b/tests/misc_testsuite/empty.wast index 5f26cd22c216..08be4a08cd8a 100644 --- a/tests/misc_testsuite/empty.wast +++ b/tests/misc_testsuite/empty.wast @@ -1,3 +1,46 @@ (module (func (export "empty"))) (invoke "empty") + +(module binary + "\00asm\01\00\00\00" ;; module header + + "\00" ;; custom section id 0 + "\0e" ;; section size + "\04name" ;; this is the `name` custom section + "\01" ;; function name subsection + "\07" ;; function name subsection size + "\01" ;; 1 function name mapping + "\ff\ff\ff\ff\0f" ;; index == u32::MAX + "\00" ;; empty string name +) + +(module binary + "\00asm\01\00\00\00" ;; module header + + "\00" ;; custom section id 0 + "\10" ;; section size + "\04name" ;; this is the `name` custom section + "\02" ;; local name subsection + "\09" ;; local name subsection size + "\01" ;; 1 indirect name map + "\ff\ff\ff\ff\0f" ;; index == u32::MAX (function) + "\01" ;; 1 name mapping + "\00" ;; index == 0 (local) + "\00" ;; empty string name +) + +(module binary + "\00asm\01\00\00\00" ;; module header + + "\00" ;; custom section id 0 + "\10" ;; section size + "\04name" ;; this is the `name` custom section + "\02" ;; local name subsection + "\09" ;; local name subsection size + "\01" ;; 1 indirect name map + "\00" ;; index == 0 (function) + "\01" ;; 1 name mapping + "\ff\ff\ff\ff\0f" ;; index == u32::MAX (local) + "\00" ;; empty string name +)