Skip to content

Fix off-by-one in aot_alloc_tiny_frame overflow check#4845

Open
sumleo wants to merge 2 commits intobytecodealliance:mainfrom
sumleo:fix/aot-tiny-frame-overflow-check
Open

Fix off-by-one in aot_alloc_tiny_frame overflow check#4845
sumleo wants to merge 2 commits intobytecodealliance:mainfrom
sumleo:fix/aot-tiny-frame-overflow-check

Conversation

@sumleo
Copy link
Contributor

@sumleo sumleo commented Feb 25, 2026

Summary

The boundary check in aot_alloc_tiny_frame (core/iwasm/aot/aot_runtime.c, line 4179) only verifies that new_frame itself doesn't exceed top_boundary, but doesn't account for the sizeof(AOTTinyFrame) bytes that are about to be written.

When new_frame equals top_boundary exactly, the check passes but the subsequent write to new_frame->func_index goes past the boundary, causing an out-of-bounds write on the wasm operand stack.

Fix

Changed the boundary check from:

if ((uint8 *)new_frame > exec_env->wasm_stack.top_boundary)

to:

if ((uint8 *)new_frame + sizeof(AOTTinyFrame) > exec_env->wasm_stack.top_boundary)

This matches the correct pattern already used in aot_alloc_frame (line 4086) and aot_alloc_standard_frame (line 4086), which both include the frame size in their boundary checks:

if ((uint8 *)frame + size > exec_env->wasm_stack.top_boundary)

Impact

Without this fix, when the wasm operand stack is nearly full and new_frame lands exactly at top_boundary, the runtime would write past the stack boundary. This could corrupt adjacent memory and lead to undefined behavior or crashes.

The boundary check in aot_alloc_tiny_frame only verifies that
new_frame itself doesn't exceed top_boundary, but doesn't account
for the sizeof(AOTTinyFrame) bytes that are about to be written.
When new_frame equals top_boundary exactly, the check passes but
the subsequent write to new_frame->func_index goes past the
boundary. This matches the correct pattern used in
aot_alloc_frame (line 4086) which includes the frame size.
Break the overflow check condition across two lines to stay within the
80-column limit enforced by clang-format.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant