Guard against underflow when sysconf(_SC_PAGESIZE) returns 0#3031
Merged
Conversation
paracycle
force-pushed
the
fix/wasi-page-size-clamp
branch
from
July 24, 2026 00:22
5e2268b to
d9196a4
Compare
On WASI in a Rust-linked wasm32 module, `sysconf(_SC_PAGESIZE)` returns 0 instead of -1. The existing fallback only checked for -1, so a 0 result flowed through to `rbs_allocator_init` where `payload_size = page_size - sizeof(rbs_allocator_page_t)` underflowed to near SIZE_MAX (unsigned wraparound). The subsequent `malloc(header_size + payload_size)` wrapped to `malloc(0)`, allocating a zero-byte arena page. Arena sub-allocations overflowed into adjacent heap memory, corrupting the lexer's string pointers and causing parse failures. The resulting corruption is memory-layout-dependent; in the Rust-linked cdylib it manifested when the constant pool's allocation overlapped the undersized arena page. Fix: extract `rbs_allocator_normalize_page_size(long)` which falls back to 4096 when the raw value is <= 0 or smaller than `sizeof(rbs_allocator_page_t)`. The WASM selftest (`rake wasm:check`) now calls it with synthetic inputs -1, 0, 1, and 65536 to verify both fallback and pass-through paths. Note: upstream's standalone reactor build returns 65536 from sysconf, so the bug does not reproduce there. The fix is defensive and preserves behavior on all platforms with a valid page size.
paracycle
force-pushed
the
fix/wasi-page-size-clamp
branch
from
July 24, 2026 00:22
d9196a4 to
33fb933
Compare
soutaro
enabled auto-merge
July 27, 2026 02:24
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
On WASI in a Rust-linked wasm32 module,
sysconf(_SC_PAGESIZE)returns 0 instead of -1. The existing fallback only checked for -1, so a 0 result flowed through torbs_allocator_initwhere:This underflowed to near
SIZE_MAX(unsigned wraparound:0 - 12 = 0xFFFFFFF4). The subsequentmalloc(sizeof(header) + 0xFFFFFFF4)wrapped tomalloc(0), allocating a zero-byte arena page. Arena sub-allocations overflowed into adjacent heap memory, corrupting the lexer'sstring.start/string.endpointers and causing parse failures.The resulting corruption is memory-layout-dependent; in the Rust-linked cdylib it manifested when the constant pool's allocation overlapped the undersized arena page.
Fix
Extract
rbs_allocator_normalize_page_size(long)which falls back to 4096 when the raw value is<= 0or smaller thansizeof(rbs_allocator_page_t).get_system_page_sizeroutes through it on both POSIX and Windows paths.Regression test
The existing
rbs_wasm_selftest(run viarake wasm:check) now callsrbs_allocator_normalize_page_sizewith synthetic inputs-1,0,1, and65536, verifying both fallback and pass-through paths.Mutation-verified (
rake wasm:check):WebAssembly selftest passed.WebAssembly selftest failed: rbs_wasm_selftest returned "0" (expected "1")+rake aborted!WebAssembly selftest passed.Scope
sysconf, so the bug does not reproduce there. The fix is defensive and preserves behavior on all platforms with a valid page size.wasm32-wasip1(Rubydex playground).