Skip to content

Commit 3f4960a

Browse files
authored
Fix a panic when validating return_call after end (#1641)
This commit fixes a mistake that was introduced in #1587 which was first released as 1.210.0 as part of `wasm-tools`. In #1587 control flow was restructured in the validator to expose an out-of-bounds access of `self.control` when a function has instructions after the final `end` instruction. The fix in this commit is to apply the same logic as `check_return` which is to explicitly check for the length of the `control` stack and return an error. This bug comes from how instructions-after-`end` are detected in the validator. Notably this erroneous condition is checked when the functions reaches EOF, not when the control stack is emptied. This is to avoid checking at all instructions that the control stack has a length greater than one and to instead defer that check to only instructions that need it. This susprising behavior, though, ended up leading to this bug.
1 parent 8c43f94 commit 3f4960a

File tree

3 files changed

+23
-0
lines changed

3 files changed

+23
-0
lines changed

crates/wasmparser/src/validator/operators.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -904,6 +904,9 @@ where
904904
/// Check that the given type has the same result types as the current
905905
/// function's results.
906906
fn check_func_type_same_results(&self, callee_ty: &FuncType) -> Result<()> {
907+
if self.control.is_empty() {
908+
return Err(self.err_beyond_end(self.offset));
909+
}
907910
let caller_rets = self.results(self.control[0].block_type)?;
908911
if callee_ty.results().len() != caller_rets.len()
909912
|| !caller_rets
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
(assert_invalid
2+
(module
3+
(func
4+
end
5+
return_call 0
6+
)
7+
)
8+
"operators remaining after end of function")
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"source_filename": "tests/local/tail-call-after-end.wast",
3+
"commands": [
4+
{
5+
"type": "assert_invalid",
6+
"line": 2,
7+
"filename": "tail-call-after-end.0.wasm",
8+
"text": "operators remaining after end of function",
9+
"module_type": "binary"
10+
}
11+
]
12+
}

0 commit comments

Comments
 (0)