Skip to content

security: fix integer overflow and OOB writes in reflection.cpp#9065

Open
sharadboni wants to merge 2 commits intogoogle:masterfrom
sharadboni:fix/security-reflection-overflow-oob
Open

security: fix integer overflow and OOB writes in reflection.cpp#9065
sharadboni wants to merge 2 commits intogoogle:masterfrom
sharadboni:fix/security-reflection-overflow-oob

Conversation

@sharadboni
Copy link
Copy Markdown

Summary

Three security fixes for the reflection mutation API, all verified with ASan/UBSan.

Fix 1: Signed integer overflow in ResizeAnyVector (CVE candidate)

delta_bytes = delta_elem * elem_size used int × int arithmetic which overflows when delta_elem × elem_size > INT_MAX. For example, a vector with 1M elements of 4096-byte structs triggers the overflow. The resulting negative delta_bytes is passed to ResizeContext, causing a massive heap underallocation followed by OOB write.

Fix: Use int64_t for the multiplication and reject overflow:

auto delta_bytes = delta_elem * static_cast<int64_t>(elem_size);
if (delta_bytes < INT_MIN || delta_bytes > INT_MAX) { return nullptr; }

Fix 2: Unchecked memset length in SetString

Before resizing, SetString calls memset(flatbuf->data() + start, 0, str->size()) to clear the old string. If start + str->size() > flatbuf->size(), this writes past the buffer. Added bounds check before the memset.

Fix 3: Unchecked field->id() index in ForAllFields

field_to_id_map is allocated with object->fields()->size() entries, but field->id() values from an attacker-controlled FlatBuffer can exceed that size, causing OOB write. Added a bounds guard.

Test

All three bugs reproduced with ASan/UBSan on the existing flatbuffers reflection library. This PR is complementary to #9046 which covers verifier OOB reads.

Three security fixes for the reflection mutation API:

1. ResizeAnyVector: signed integer overflow in delta_bytes
   The computation `delta_elem * elem_size` used int × int which overflows
   when the product exceeds INT_MAX (e.g., 1M elements × 4096-byte elem).
   Use int64_t arithmetic and reject overflow before passing to ResizeContext.

2. SetString: unchecked memset length before ResizeContext
   The memset clearing the old string used str->size() from the FlatBuffer
   without validating that start+str->size() <= flatbuf->size(). Added the
   bounds check so only valid in-bounds bytes are zeroed.

3. ForAllFields: unchecked field->id() index
   field_to_id_map.resize(object->fields()->size()) but field->id() values
   from an untrusted FlatBuffer can exceed that size, causing OOB write.
   Added a bounds guard before the assignment.

All three bugs are ASan/UBSan verified.
@github-actions github-actions Bot added c++ codegen Involving generating code from schema labels Apr 27, 2026
Cast index to uint64_t before multiplying by element_stride to prevent
uint32_t overflow when computing large offsets in IndirectHelper<OffsetT<T>>::Read.
Previously, i * element_stride (both uint32_t) could wrap around, producing
a pointer far outside the buffer and causing a SIGSEGV.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

c++ codegen Involving generating code from schema

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant