Skip to content

Commit e5b127c

Browse files
authored
Add missing stack map declaration for array.new_elem (#12936)
`translate_array_new_elem` created a GC reference (array ref) via a libcall but did not call `builder.declare_value_needs_stack_map()` on the result. This meant the reference was not included in stack maps at subsequent safepoints, so if a GC occurred, the reference became stale (leading to use-after-free within the GC heap sandbox).
1 parent 0d66dff commit e5b127c

2 files changed

Lines changed: 29 additions & 1 deletion

File tree

crates/cranelift/src/func_environ.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2766,7 +2766,9 @@ impl FuncEnvironment<'_> {
27662766
libcall,
27672767
&[vmctx, interned_type_index, elem_index, elem_offset, len],
27682768
);
2769-
Ok(builder.func.dfg.first_result(call_inst))
2769+
let array_ref = builder.func.dfg.first_result(call_inst);
2770+
builder.declare_value_needs_stack_map(array_ref);
2771+
Ok(array_ref)
27702772
}
27712773

27722774
pub fn translate_array_copy(
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
;;! gc = true
2+
;;! bulk_memory = true
3+
4+
(module
5+
(type $s (struct (field (mut i32))))
6+
(type $arr (array (ref null $s)))
7+
8+
(elem $e (ref null $s) (struct.new $s (i32.const 42)))
9+
10+
(import "wasmtime" "gc" (func $gc))
11+
12+
(func (export "test") (result i32)
13+
(array.new_elem $arr $e (i32.const 0) (i32.const 1))
14+
15+
(call $gc)
16+
(drop (struct.new $s (i32.const 0)))
17+
(drop (struct.new $s (i32.const 0)))
18+
(drop (struct.new $s (i32.const 0)))
19+
(drop (struct.new $s (i32.const 0)))
20+
(drop (struct.new $s (i32.const 0)))
21+
22+
(struct.get $s 0 (array.get $arr (i32.const 0)))
23+
)
24+
)
25+
26+
(assert_return (invoke "test") (i32.const 42))

0 commit comments

Comments
 (0)