Skip to content

[BUG] AOT loader: NULL pointer dereference in load_types #4877

@srberard

Description

@srberard

This issue was reported to the WAMR team by @Nughm3

Summary

WAMR's AOT file loader lacks a null-pointer guard when resolving parent type inheritance in load_types(). A crafted 208-byte AOT binary with a forward-referencing parent_type_idx dereferences an uninitialized slot in the types array, crashing any application that loads untrusted .aot files.

Details

Overview

The load_types() function in WAMR's AOT loader resolves parent type references using an index read directly from the AOT binary. When the optional AOT validator is disabled (the default configuration), this index is not bounds-checked against the current type index. A crafted AOT file can set parent_type_idx to reference a type slot that has not yet been populated (still NULL from the initial calloc), causing a NULL pointer dereference when the code accesses parent_type->root_type.

Root Cause

The module->types array is allocated via loader_malloc (which uses calloc) at line 1767, initializing all slots to NULL. Types are populated sequentially in a loop (line 1774). The parent type index validation at line 1819 is compiled in only when WASM_ENABLE_AOT_VALIDATOR is enabled:

#if WASM_ENABLE_AOT_VALIDATOR != 0
    // ...
    if (parent_type_idx >= i) {
        set_error_buf(error_buf, error_buf_size,
            "parent type index must be smaller than current type index");
        goto fail;
    }
#endif

Without the validator, a parent_type_idx pointing to a not-yet-populated slot passes through unchecked.

Reference: https://github.com/bytecodealliance/wasm-micro-runtime/blob/c46b10dcbc616a3a158f05cad2ab716b52b0803a/core/iwasm/aot/aot_loader.c#L1810C1-L1825C7

Vulnerable Code Path

for (j = i - rec_idx; j <= i; j++) {
    AOTType *cur_type = module->types[j];
    parent_type_idx = cur_type->parent_type_idx;
    if (parent_type_idx != (uint32)-1) { /* has parent */
        AOTType *parent_type = module->types[parent_type_idx]; // NULL if not yet populated
        module->types[j]->parent_type = parent_type;
        module->types[j]->root_type = parent_type->root_type;  // SEGV: NULL + 0x8

The root_type field sits at offset +0x8 in the WASMType struct, so dereferencing NULL->root_type reads address 0x0000000000000008, producing the observed SEGV.

Reference: https://github.com/bytecodealliance/wasm-micro-runtime/blob/c46b10dcbc616a3a158f05cad2ab716b52b0803a/core/iwasm/aot/aot_loader.c#L2077C13-L2084C74

PoC

Download the reproduction files.

With Docker

docker build -t wamr-nullptr-pov .
docker run --rm wamr-nullptr-pov

To verify the patch:

docker build -t wamr-nullptr-patch -f Dockerfile.patch .
docker run --rm wamr-nullptr-patch

Manually

  1. Clone and build WAMR with ASan and GC enabled:
git clone --depth 1 https://github.com/bytecodealliance/wasm-micro-runtime wamr
cd wamr/product-mini/platforms/linux
mkdir build && cd build
cmake .. \
-DCMAKE_C_COMPILER=clang \
-DCMAKE_C_FLAGS="-fsanitize=address -g -O1" \
-DWAMR_BUILD_AOT=1 \
-DWAMR_BUILD_INTERP=0 \
-DWAMR_BUILD_GC=1 \
-DWAMR_BUILD_REF_TYPES=1 \
-DWAMR_BUILD_BULK_MEMORY=1 \
-DWAMR_BUILD_SIMD=1
cmake --build .
  1. Run against the crash artifact:
ASAN_OPTIONS="detect_leaks=0:abort_on_error=1" ./iwasm crash-aot-load-types-nullptr.bin

Expected output:

==1==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000008
==1==The signal is caused by a READ memory access.
==1==Hint: address points to the zero page.

Impact

  • Denial of service: any application using wasm_runtime_load() to load untrusted AOT modules crashes immediately. This affects WAMR-based runtimes, edge computing platforms, and IoT firmware that accept user-supplied .aot files.
  • Remote trigger: if the application accepts AOT files over the network (e.g., serverless function deployment, OTA firmware update), the crash is remotely exploitable without authentication.

Credits & supplementary information

  • Found by: Isaac Hung
  • Tools used: Atlantis OSS-CRS, libFuzzer

About us

We are Team Atlanta from Georgia Institute of Technology, winners of DARPA's AI Cyber Challenge (AIxCC). We're reaching out to submit a vulnerability report that we identified using our system, Atlantis, in your project. This effort is recommended by DARPA's initiative to apply competition technologies to real-world open source projects.
We have built an AI-enhanced CRS (Cyber Reasoning System) for automatic vulnerability detection and repair.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions