Skip to content

verifier: validate NULL buffer in Verifier and flexbuffers::VerifyBuffer - #9276

Open
filtede98 wants to merge 1 commit into
google:masterfrom
filtede98:fix-verifier-null-buffer-guards
Open

filtede98 wants to merge 1 commit into
google:masterfrom
filtede98:fix-verifier-null-buffer-guards

Conversation

@filtede98

Copy link
Copy Markdown

Description

This PR strengthens NULL pointer safety and defensive checks across flatbuffers::Verifier and flexbuffers::VerifyBuffer:

  1. flexbuffers.h:

    • In Verifier::VerifyBuffer(), pointer arithmetic auto end = buf_ + size_; followed by auto byte_width = *--end; dereferenced unmapped memory when buf_ == nullptr and size_ >= 3, leading to a hardware segmentation fault instead of gracefully returning false. Added Check(buf_ != nullptr && size_ >= 3).
    • In flexbuffers::VerifyBuffer(), added if (!buf) return false; to fail immediately and avoid unneeded allocations in reuse_tracker_.
    • In Verifier::VerifyFrom and Verifier::VerifyBefore, added buf_ != nullptr checks to ensure range validation never succeeds on a null buffer pointer.
    • Guarded reuse_tracker_ initialization in Verifier::Verifier() with if (buf_ && reuse_tracker_).
  2. verifier.h:

    • In VerifierTemplate::Verify(), added buf_ != nullptr to range verification. Previously, Verify() evaluated only bounds against size_, causing VerifyOffset() to succeed on offset 0 for a null buffer and subsequently dereference nullptr in ReadScalar<OffsetT>(buf_ + start).
    • In VerifyBufferFromStart(), added buf_ != nullptr check in the minimum buffer size guard: Check(buf_ != nullptr && size_ >= FLATBUFFERS_MIN_BUFFER_SIZE).
  3. Regression Tests:

    • In tests/flexbuffers_test.cpp and tests/flexbuffers_test.h, added FlexBuffersVerifyNullBufferTest() validating that passing null buffers (both with and without reuse_tracker) returns false without crashing.
    • In tests/test.cpp, added VerifierNullBufferTest() verifying that passing a null buffer to flatbuffers::Verifier returns false in VerifyBuffer<Monster>() and Verify().

Signed-off-by: Filippo Tedeschi filippotedeschi98@gmail.com

1. In flexbuffers.h, Verifier::VerifyBuffer() performed pointer
   arithmetic (buf_ + size_) and immediately dereferenced *--end
   without validating that buf_ is non-null. When a null buffer is
   passed with size_ >= 3, this leads to a segmentation fault rather
   than returning false. Additionally, flexbuffers::VerifyBuffer()
   instantiated the verifier and attempted to clear and resize
   reuse_tracker_ even when buf is NULL. Add null checks in
   Verifier::VerifyBuffer(), flexbuffers::VerifyBuffer(),
   Verifier::VerifyFrom, Verifier::VerifyBefore, and guard
   reuse_tracker_ initialization.

2. In verifier.h, VerifierTemplate::Verify() and VerifyBufferFromStart()
   checked buffer bounds against size_ but did not verify that buf_
   is non-null. When a Verifier is initialized with a null buffer
   pointer and VerifyBuffer<T>() is invoked, Verify() returned true
   for initial offsets, causing ReadScalar<OffsetT>() to dereference
   a null pointer. Add buf_ != nullptr checks to
   VerifierTemplate::Verify() and VerifyBufferFromStart().

3. In tests/flexbuffers_test.cpp and tests/test.cpp, add regression
   tests verifying that passing null buffer pointers to
   flexbuffers::VerifyBuffer() and flatbuffers::Verifier gracefully
   returns false without crashing.

Signed-off-by: Filippo Tedeschi <filippotedeschi98@gmail.com>

This branch has not been deployed

No deployments
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