Skip to content

fix: add bounds assertions and safety docs for FlexBuffer OOB reads#9155

Open
samrigby64 wants to merge 1 commit into
google:masterfrom
samrigby64:fix/flexbuffer-oob-reads
Open

fix: add bounds assertions and safety docs for FlexBuffer OOB reads#9155
samrigby64 wants to merge 1 commit into
google:masterfrom
samrigby64:fix/flexbuffer-oob-reads

Conversation

@samrigby64

Copy link
Copy Markdown

Problem

Three locations in flexbuffers.h can trigger out-of-bounds reads (CWE-125) when called on unverified input:

  1. Sized::read_size() (line ~241) reads byte_width_ bytes before data_. A malformed byte_width_ (not 1/2/4/8) or a data_ pointer too close to the buffer start causes a read before the allocation.
  2. Map::Keys() (line ~351) accesses data_ - byte_width_*5 for the three Map prefix fields. Same root cause as Don't just blindly double the buffer size #1.
  3. Vector::operator[] (line ~962) uses read_size() — which calls read_size() — as the loop bound, then reads type bytes at data_ + len*byte_width_. A corrupt len can push this read arbitrarily past the buffer end.
    The FlexBuffer Verifier already catches all three patterns when flexbuffers::VerifyBuffer() is called before data access (it calls VerifyBeforePointer for the size prefix and VerifyFromPointer for the element and type-byte spans). These changes make the contract explicit.

Changes

  • Add FLATBUFFERS_ASSERT in read_size() and Keys() that byte_width_ is one of the four legal values; a corrupt value will now fire in debug builds.
    • Add clarifying comments at all three sites referencing the Verifier requirement and the CWE number so callers understand the preconditions.

Testing

No behavioral change for verified buffers; asserts fire only on malformed input that the Verifier would already have rejected. This is a hardening / defense-in-depth change.

@samrigby64 samrigby64 requested a review from dbaileychess as a code owner June 24, 2026 18:34
@google-cla

google-cla Bot commented Jun 24, 2026

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@github-actions github-actions Bot added the c++ label Jun 24, 2026
Three locations in flexbuffers.h can trigger out-of-bounds reads (CWE-125)
when called on unverified input:

1. Sized::read_size() (line ~241): reads `byte_width_` bytes before data_.
   A malformed byte_width_ (not 1/2/4/8) or a data_ pointer too close to
   the buffer start causes a read before the allocation.

2. Map::Keys() (line ~351): accesses data_ - byte_width_*3 for the three
   Map prefix fields. Same root cause as google#1.

3. Vector::operator[] (line ~962): uses size() — which calls read_size() —
   as the loop bound, then reads type bytes at data_ + len*byte_width_. A
   corrupt len can push this read arbitrarily past the buffer end.

The FlexBuffer Verifier already catches all three patterns when
flexbuffers::VerifyBuffer() is called before data access (it calls
VerifyBeforePointer for the size prefix and VerifyFromPointer for the
element and type-byte spans). These changes make the contract explicit:

- Add FLATBUFFERS_ASSERT in read_size() and Keys() that byte_width_ is one
  of the four legal values; a corrupt value will now fire in debug builds.
- Add clarifying comments at all three sites referencing the Verifier
  requirement and the CWE number so callers understand the precondition.

Reported by: Sam Rigby (samrigby432@outlook.com)
@samrigby64 samrigby64 force-pushed the fix/flexbuffer-oob-reads branch from f1842d9 to 1164b20 Compare June 24, 2026 18:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant