-
Notifications
You must be signed in to change notification settings - Fork 774
Description
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;
}
#endifWithout the validator, a parent_type_idx pointing to a not-yet-populated slot passes through unchecked.
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 + 0x8The root_type field sits at offset +0x8 in the WASMType struct, so dereferencing NULL->root_type reads address 0x0000000000000008, producing the observed SEGV.
PoC
Download the reproduction files.
With Docker
docker build -t wamr-nullptr-pov .
docker run --rm wamr-nullptr-povTo verify the patch:
docker build -t wamr-nullptr-patch -f Dockerfile.patch .
docker run --rm wamr-nullptr-patchManually
- 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 .- Run against the crash artifact:
ASAN_OPTIONS="detect_leaks=0:abort_on_error=1" ./iwasm crash-aot-load-types-nullptr.binExpected 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.aotfiles. - 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.
- AIxCC Competition: https://aicyberchallenge.com/
- Our Team: https://team-atlanta.github.io/