Skip to content

Harden C++ FlatBuffers root access with checked verifier-backed APIs#8977

Open
0xEaS1 wants to merge 2 commits intogoogle:masterfrom
0xEaS1:flatbuffers-checked-root-api
Open

Harden C++ FlatBuffers root access with checked verifier-backed APIs#8977
0xEaS1 wants to merge 2 commits intogoogle:masterfrom
0xEaS1:flatbuffers-checked-root-api

Conversation

@0xEaS1
Copy link

@0xEaS1 0xEaS1 commented Mar 12, 2026

Summary

This change adds new C++ helper APIs that combine FlatBuffers verification with obtaining the typed root pointer, providing a secure-by-default way to consume untrusted buffers while keeping all existing APIs and behavior intact.

Security motivation

  • Many FlatBuffers deployments deserialize data that ultimately comes from untrusted sources such as network messages, files, or IPC buffers.
  • Today, the recommended pattern is “verify first via flatbuffers::Verifier, then call GetRoot<T>()”; in practice, it is easy for callers to accidentally skip or mis-order the verification step, which can result in undefined behavior on malformed or adversarial inputs.
  • The new checked helpers make the safe pattern the easiest pattern by providing a single function that:
    • Runs the C++ verifier with configurable limits, and
    • Only returns a typed root pointer when verification succeeds, otherwise returning nullptr.
  • This is a secure-by-design memory safety improvement: it systematically reduces the risk of out-of-bounds and misaligned accesses driven by untrusted buffers, and aligns the C++ surface more closely with the safety guarantees already provided by the Rust runtime.

Changes

  • Add flatbuffers::GetRootChecked and flatbuffers::GetSizePrefixedRootChecked (and their mutable variants) to include/flatbuffers/flatbuffers.h:
    • Overloads that accept:
      • (const void* buf, size_t len, const Verifier::Options& opts = Verifier::Options())
      • (const void* buf, size_t len, const char* identifier, const Verifier::Options& opts = Verifier::Options())
    • Internally construct a flatbuffers::Verifier and call VerifyBuffer<T>() / VerifyBuffer<T>(identifier) or VerifySizePrefixedBuffer<T, SizeT>() as appropriate.
    • Return nullptr when verification fails instead of a potentially unsafe typed pointer.
  • Add corresponding mutable helpers:
    • GetMutableRootChecked<T>(void* buf, size_t len, ...)
    • GetMutableSizePrefixedRootChecked<T, SizeT>(void* buf, size_t len, ...)
    • These build on the const versions and preserve the existing mutation semantics when verification succeeds.
  • These helpers live in flatbuffers/flatbuffers.h, which already includes flatbuffers/verifier.h, so call sites don’t need any additional includes.
  • Add a small test in tests/monster_test.cpp (CheckedRootApiTest) to exercise the new APIs against a known-good Monster buffer and a truncated buffer:
    • Confirms that valid buffers round-trip through GetRootChecked<Monster> when given the correct identifier.
    • Confirms that truncated buffers cause GetRootChecked to return nullptr instead of exposing undefined behavior.

Testing

  • C++ tests:
    • Existing monster_test suite passes with the new helpers in place.
    • CheckedRootApiTest covers successful and failing verification paths for GetRootChecked<Monster>.
  • Fuzzing and sanitizers:
    • The new helpers are thin wrappers around the existing, well-fuzzed C++ verifier logic.
    • When built with FLATBUFFERS_CODE_SANITIZE enabled, the additional code paths are covered by the same ASan/UBSan configuration that protects the rest of the C++ runtime.

Backwards compatibility / migration notes

  • No existing APIs are removed or changed:
    • GetRoot<T>(), GetMutableRoot<T>(), GetSizePrefixedRoot<T>(), and GetMutableSizePrefixedRoot<T>() continue to behave exactly as before.
  • The new helpers are entirely additive:
    • Existing callers do not need to change anything.
    • Applications that currently implement their own “verify + get root” pattern can migrate to the checked helpers at their own pace.
  • The verifier options structure (flatbuffers::Verifier::Options) is reused as-is, so existing tuning of depth/table limits and alignment checks is preserved when callers choose to pass custom options to the checked helpers.

@0xEaS1 0xEaS1 requested a review from dbaileychess as a code owner March 12, 2026 15:43
@google-cla
Copy link

google-cla bot commented Mar 12, 2026

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 Mar 12, 2026
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