[5] Wasm GC struct.new_default Information Leak via Missing v128 Initialization
Severity: Medium | Component: JSC Wasm OMG JIT | 4be0a7f
Rated Medium because the observable effect is a reliable leak of 8 bytes of uninitialized process memory per struct allocation, useful for ASLR bypass — the missing init branch is confirmed with confidence 0.95 from the diff, though whether the backing store is pre-zeroed or relies entirely on per-field initialization is unverified.
Initialize v128 fields in struct.new_default with a v128_t { }. Also drive-by changes array.new_default to use the constant() helper.
Source/JavaScriptCore/wasm/WasmOMGIRGenerator.cpp
for (StructFieldCount i = 0; i < structType.fieldCount(); ++i) {
Value* initValue;
- if (Wasm::isRefType(structType.field(i).type))
+ auto fieldType = structType.field(i).type;
+ if (Wasm::isRefType(fieldType))
initValue = m_currentBlock->appendNew<WasmConstRefValue>(m_proc, origin(), JSValue::encode(jsNull()));
- else if (typeSizeInBytes(structType.field(i).type) <= 4)
+ else if (typeSizeInBytes(fieldType) == 16)
+ initValue = constant(V128, v128_t { });
+ else if (typeSizeInBytes(fieldType) <= 4)
initValue = constant(Int32, 0);
else
initValue = constant(Int64, 0);
JSTests/wasm/gc/struct-new-default-v128.js
+ (type $S1 (struct (field $vec (mut v128))))
+ (func (export "leak") (result i64)
+ (struct.new_default $S1)
+ (struct.get $S1 0)
+ (i64x2.extract_lane 1)
+ )
+...
+ for (let i = 0; i < 1000000; i++) {
+ const value = instance.exports.leak();
+ assert.eq(value, 0n);
+ }
Missing size-class branch for 128-bit SIMD fields in Wasm struct default-initialization, causing partial initialization and information leakage.
Patch Details
In OMGIRGenerator::addStructNewDefault, the field initialization loop lacked a branch for 16-byte (v128) fields. Before the fix, a v128 field (size 16) was not a ref type and its size was > 4, so it fell into the else branch and was initialized as constant(Int64, 0) — an 8-byte zero value for a 16-byte slot. The fix inserts an explicit typeSizeInBytes(fieldType) == 16 check that initializes v128 fields with constant(V128, v128_t { }), a proper 128-bit zero. A drive-by change in addArrayNewDefault replaces a verbose Const128Value construction with the same helper for consistency.
Background
Wasm GC struct.new_default creates a new struct instance with all fields set to their default (zero) values per the WebAssembly GC specification. v128 is a 128-bit SIMD type used in Wasm SIMD and Wasm GC; its fields occupy 16 bytes in memory. The OMG tier is JSC's top-tier optimizing JIT for Wasm, which compiles hot functions via B3 IR. The constant() helper in the OMG IR generator creates typed constant B3 values; using constant(Int64, 0) for a 16-byte field produces a value that only covers 8 of the 16 required bytes, leaving the upper half uninitialized.
Analysis
The root cause is a missing case in a size-based type dispatch. The initialization logic branched on ref types first, then fields with size ≤ 4 bytes (Int32), and fell through to Int64 (8 bytes) for everything else. A v128 field has typeSizeInBytes == 16, so it matched the else branch and was initialized with an 8-byte zero. This left the upper 8 bytes of the 16-byte v128 slot uninitialized. The JIT-compiled code writes only 8 zero bytes into a 16-byte field, and subsequent reads of the field (e.g., i64x2.extract_lane 1) return whatever happened to be in the uninitialized upper half — if the backing store relies on per-field initialization rather than being pre-zeroed, this exposes stale heap or stack contents to JavaScript.
Aaa Aaaa Aaaa Aaaaaaaaaaaa Aaa Aaaaa Aaaaaaaa a Aaaa Aaaaaa Aaaa a Aaaaaa Aaaa Aaaaaaaaaa a Aaaa Aaaaaa a Aaaaaaaa Aaaa Aaaaaaaa Aaaaaaaaaaaaaaaaaaaa Aaaaaaaa Aa Aaaaaaaaaaaa Aaa Aaaaaaaaaaaaaaaaaaa Aa Aa Aaaa Aaa Aaaaa a Aaaaaa Aaa Aa a Aaa Aaaa Aaaaaaaaaa Aaaaaaaaaaa Aa Aaaaaa Aaa Aaaaaaaaaaaa Aaaa Aaaaaaaaa Aaaaaaa Aaa Aaaaa Aaaaaa Aaaa a Aaaaaa Aaa Aaaa Aaa Aaaaa a Aaaaa Aaaaa Aaaaaaa Aaaaa Aaaa Aaaaa Aaaaaaa Aaa Aaaaaaaaa Aa Aaaaa
Aa Aaaaaaaa Aaaaa Aaaaaaaaaa Aaaaaa Aaaaaaaaaaaaaaaaaaa Aaaaaaa Aaaa Aaaa Aaaaaa Aaa Aaaaaaa Aaaa Aaaaaaa Aaaaaaaaaa Aa Aa a Aaaaa Aa Aaaaaaaaaaaaa Aaaaaaa Aaaaaa Aaa Aaaaaaaaaa Aa a Aaaaaaaaaa Aaaaaaa Aaaaaa Aaaa Aaaaaaaa Aaaaa Aa Aaaaaa Aaa Aaaa Aaaaaa Aaaa Aaaaaaa Aaaa a Aaaaaaaa Aaaaaa Aaaaaaaaaa Aaaaaaaaaaaaaa
Aaaa Aaaaaaaaaaaaa Aaaaaaa Aaaaaa Aaaaaaaaaaaaaaa Aaaaaa Aaa Aaaaaaaa Aaaaaaaa Aaa Aaaa Aaaa Aaaaaaaa Aaaaaaaaaaaaaaaaaaaa Aa Aaaaaaaaaaaaaaa Aaa Aaaaaaa Aaa Aaaaaaa Aaaa Aaaaaa Aaaaaaaa Aaaa Aaaaaaaaaa Aaa Aaaa Aaaaaa Aaaa Aaa Aaaaaa Aaa Aaaaaaaaaa Aaaaaaa Aaaaaaaa Aaa Aaaaaa Aaaaaaaa Aaaaa Aaaaaaaaaaaaa Aaa Aaaaaaaaaaaa Aa Aaaaaaaa Aaaaaaaaaaaaaaaa
Aaa Aaaa Aa Aaaaaaaaaaaaa Aaaa Aaaaaaa Aaa Aaaaa Aaaaaa Aaaaaaaa Aaaaaaaaaa Aaaaa Aaaa Aaaa Aa Aaaaaaa Aa Aaaaa Aaaa Aaaa Aaaa Aaaaaaaaaaaa Aaaaaaa Aa Aaaaaaaa Aaaaaaa Aaaa a Aaaaaaaaaa Aaaaaaaa Aaaa Aaa Aa a Aaaaaa Aa a Aaaaaaaaa Aaa Aaaaaa Aaa Aaaaaa Aaaaaa Aaaaaa a Aaaaaaa Aaaa Aaaaaaaa Aaaaa Aaaaaaa Aa Aaa Aaaaa Aaaaa Aaaa Aa a Aaaaa Aa Aaaa Aaaa Aaaa Aaaaa Aa Aaaa Aa Aaaaaaa Aaa Aaaaa Aaaaa Aaa Aaaaaa
Audit directions
a Aaaaaaaa Aaaaaaaaaa Aaaa Aaaaaaaa Aaaa a Aaaaaaaaa Aaaaaa Aaaaaa Aaaa Aaaaaaaaaa Aaaaaaa a Aaaaaaa Aaaaa Aaaaaa Aaaa Aaa Aaaaa Aaaaa Aaa Aaaaaa Aaa Aaaaaaaaa Aaaaaaaa Aaaaaaa Aaaa Aaaaaaaaaaaa Aaaaa Aaa Aaaa Aa Aaaaaaaaaa Aaaaa Aaaa Aaaaaa Aaaaaaaaaaaaaaaaaaa Aaa Aaaaaaa Aaaaaaaaaaaaaaaaa Aa Aaaaaaaaaaaaa Aaaaaaaa Aaaaaa Aaaa Aaaa Aa Aaaaaaaa Aaaaaaaaaaaa Aaaaa Aaa Aaa Aaaaa Aaaaaaaaaaaaaaaaaaaaa Aaaaaaaaaa Aaa a Aaaaa Aaaaaaa Aaaaa Aaaa a Aaaaaa Aa Aaaaaaa Aaaa Aaaaaaaaaa
a Aaaaaaaa Aaaaaaaaaa Aaaaaaaaaaaaa Aaaaaaaaaaaaaa Aaaaaa Aaa Aaaaaa Aaaaa Aaaaaaaaaaaaaaa Aaaaaaaaaaaaaa Aaaaaaaaaaaaaaaaaaaaa Aaa Aaaaaaaaaaaaaa Aaaaaa Aaa Aaaaa Aaaaa Aaaa Aaaaaa Aaaaaaaaaaaaaaaaaaa Aa Aaaaaa Aaaa Aaaaa Aaaa Aaaa Aaaa Aaaaaaaa a Aaaaaaa Aaaaa Aaaaaaa Aaa Aaaa Aaaaa Aaaaa Aaaaaaaaa Aaaaa Aaaa Aaa Aaaaaaaaaaaaaaaaa Aaa Aaaaaaaaaaaaa Aa Aaaaaaaaaaaaaa Aaaaaa
a Aaaaaaaa Aaaaaaaaaaa Aaaaa Aaa Aaaaaaa Aaaaaaaaaaaaaa Aa Aaaaaaaaaaaa Aaaaaaaaaaa Aaa Aaa Aaaa Aaaa Aaaaaaaaa Aaa Aaaaaaaaaaa Aa Aaaaaaa Aaaaaaaaa Aaaaaaa Aaaa Aaaa Aaa Aaaa Aaaaaaaaaa Aa Aaaaaaaaaa Aaaaa Aaaaa Aaaaa Aaaaaaaaaaaaaaaaaaaa Aaa Aaaaaaaaaaaaaaaaaaaaa Aaaaaaaaaa Aaaaa Aa Aaaaa Aaaaaaa Aaa Aaaaaaa Aaaaa Aa Aaaaaaaaaa Aa Aaaaaa Aaaaaaaa Aa Aaaaaaaaa Aaaaaaaaaaaaaa a Aa Aaa Aaaaaaa Aaa Aaaaaa Aaaaa Aaaa Aaaaa Aaaaaaa