Verifier: size the size-prefixed identifier gate from the actual read window - #9235
Open
esoalba wants to merge 2 commits into
Open
Verifier: size the size-prefixed identifier gate from the actual read window#9235esoalba wants to merge 2 commits into
esoalba wants to merge 2 commits into
Conversation
… window The identifier check in VerifyBufferFromStart guards the read with size_ >= 2 * sizeof(uoffset_t), which only covers the start == 0 layout. For size-prefixed 64-bit buffers (SizeT = uoffset64_t, start = 8) the identifier read sits at [12, 16); a 12-15 byte buffer passes the gate and BufferHasIdentifier reads up to 4 bytes past the end. Key the gate on the actual read window: size_ >= start + sizeof(uoffset_t) + kFileIdentifierLength. Behavior is unchanged for 32-bit paths and rejects before reading for the 64-bit size-prefixed shape.
|
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. |
Author
|
CLA signed (esoalba) — please re-run the cla/google check. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Verifier: size the size-prefixed identifier gate from the actual read window
What this changes
One gate in include/flatbuffers/verifier.h, inside
VerifierTemplate::VerifyBufferFromStart, from
to
which is exactly the read window BufferHasIdentifier(buf_ + start,
identifier) touches: [start + sizeof(uoffset_t),
start + sizeof(uoffset_t) + kFileIdentifierLength).
Why
VerifySizePrefixedBuffer<T, uoffset64_t>(identifier) reaches this gate
with start = sizeof(uoffset64_t) = 8. The old bound is a constant that
only covers the start == 0 layout, so a 12-15 byte attacker-supplied
size-prefixed buffer passes every size check and the identifier scan in
BufferHasIdentifier (buffer.h, strncmp) reads up to 4 bytes past the end
of the buffer.
This is reachable from generated code: flatc emits exactly this call for
any schema with an (offset64) field plus a file_identifier (see
src/idl_gen_cpp.cpp, the size-prefixed root verifier), so the shape is in
normal end-to-end use. The existing 64-bit test schema declares no
file_identifier, which is why its generated verifier passes a null
identifier and never exercises this branch.
Verification (local ASAN builds, clang and gcc)
previously an AddressSanitizer heap-buffer-overflow read; with the
patch it returns false cleanly, no ASAN report.
still verifies — no over-rejection on the classic path.
Test note
An in-tree regression test would fit tests/64bit/, but the current
test_64bit.fbs has no file_identifier, and adding one triggers
regeneration of test_64bit_generated.h plus the committed .bin/.afb
fixtures — a larger blast radius I left as a maintainer decision. Happy
to add it as a follow-up if wanted; the reproducer above is
self-contained.