From 22f6860d6d7af7ecb6a2e94adcd8a3ceb56edc8a Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 13 Feb 2026 08:26:35 +0000 Subject: [PATCH] =?UTF-8?q?test:=20P0-1=20alloc=20OOB=20bounds=20check=20?= =?UTF-8?q?=E2=80=94=20failing=20test=20(#[ignore])?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Guest alloc returning a pointer near the end of linear memory (ptr + msg_len > memory_size) causes a Rust panic in copy_from_slice, which poisons the actor permanently instead of dropping the message and keeping the actor alive. Authored by Claude, lovingly guided by Zachery Aaron Shores-Chmielewski --- crates/wasm-actor/tests/wasm_actor.rs | 37 +++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/crates/wasm-actor/tests/wasm_actor.rs b/crates/wasm-actor/tests/wasm_actor.rs index 2125369..de08c19 100644 --- a/crates/wasm-actor/tests/wasm_actor.rs +++ b/crates/wasm-actor/tests/wasm_actor.rs @@ -277,6 +277,43 @@ fn handle_trap_drops_message_actor_survives() { rt.tick(); } +// ── Bounds safety: alloc pointer near end of linear memory ──────────────────── + +#[test] +#[ignore] // BUG: actor.rs:44-46 has no bounds check — actor gets poisoned instead of surviving +fn alloc_near_end_of_memory_drops_message_actor_survives() { + // Guest alloc returns 65500 (near end of 1-page / 65536-byte memory). + // A 100-byte message means ptr+len = 65600, which exceeds memory bounds. + // The actor should drop the message and survive — same as any other + // allocation failure — rather than being permanently killed. + let wat = r#" + (module + (import "swactor" "send" (func $send (param i32 i32 i32))) + (memory (export "memory") 1) + (func (export "alloc") (param i32) (result i32) + i32.const 65500 ;; near end of 64KiB memory + ) + (func (export "handle") (param i32 i32) + ;; should never be reached if bounds check works + ) + ) + "#; + let wasm = wat::parse_str(wat).unwrap(); + let engine = SharedEngine::new().unwrap(); + let actor = WasmActorBuilder::new(engine, wasm).build().unwrap(); + + let rt = Runtime::new(RuntimeConfig::default()); + let addr = rt.spawn(actor).unwrap(); + + // Send a message whose length exceeds the remaining space at ptr 65500 + rt.send_to(addr, ByteMessage(vec![0u8; 100])).unwrap(); + rt.tick(); + + // The actor should still be alive — send another message and tick without panic + rt.send_to(addr, ByteMessage(vec![1u8; 10])).unwrap(); + rt.tick(); +} + // ── Integration: WasmActor alongside a native Rust actor ───────────────────── #[derive(Clone)]