Check flatbuffer offset when verification is minimal#17129
Check flatbuffer offset when verification is minimal#17129
Conversation
🔗 Helpful Links🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/executorch/17129
Note: Links to docs will display an error until the docs builds have been completed. ❌ 1 Awaiting Approval, 9 New Failures, 21 PendingAs of commit 13ba046 with merge base 6c02866 ( NEW FAILURES - The following jobs have failed:
This comment was automatically generated by Dr. CI and updates every 15 minutes. |
This PR needs a
|
8fc7c5f to
3b4ce0c
Compare
There was a problem hiding this comment.
Pull request overview
This pull request adds minimal verification for flatbuffer root offsets to prevent crashes when InternalConsistency verification is disabled (to save binary size). The PR also changes the behavior when InternalConsistency verification is requested but not available - it now returns an error instead of just logging a warning.
Changes:
- Added bounds checking for the flatbuffer root offset in minimal verification mode to catch corruption early
- Changed behavior when InternalConsistency verification is unavailable from logging at Info level to logging at Error level and returning Error::NotSupported
- Added a test to verify that invalid root offsets are caught by minimal verification
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| runtime/executor/program.cpp | Implements minimal verification by checking root offset bounds and makes InternalConsistency unavailability an error instead of a warning |
| runtime/executor/test/program_test.cpp | Adds test case to verify that obviously invalid root offsets are rejected during minimal verification |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // Minimal verification: check that the root table offset is within bounds. | ||
| // The first 4 bytes of the flatbuffer contain an offset to the root table. | ||
| ET_CHECK_OR_RETURN_ERROR( | ||
| program_data->size() >= sizeof(flatbuffers::uoffset_t), | ||
| InvalidProgram, | ||
| "Program data size %zu is too small for flatbuffer header", | ||
| program_data->size()); | ||
| uint32_t root_offset = flatbuffers::ReadScalar<flatbuffers::uoffset_t>( | ||
| program_data->data()); | ||
| // The root table is at buf + root_offset, and must have at least a | ||
| // vtable offset (soffset_t) at that position. | ||
| ET_CHECK_OR_RETURN_ERROR( | ||
| root_offset <= program_data->size() - sizeof(flatbuffers::uoffset_t), | ||
| InvalidProgram, | ||
| "Root table offset %u exceeds program size %zu", | ||
| root_offset, | ||
| program_data->size()); |
There was a problem hiding this comment.
The new Minimal verification check only enforces an upper bound on the flatbuffer root table offset. Since this program format uses a FlatBuffers file_identifier (checked via ProgramBufferHasIdentifier), Minimal verification should also ensure the root offset cannot point into the header/identifier region (e.g., require root_offset >= sizeof(uoffset_t) + file identifier length, and that the buffer is at least that large). Without a lower-bound check, a corrupted root_offset like 4 can still pass this check and cause GetProgram() to interpret the identifier bytes as a table, risking out-of-bounds reads later during parsing.
Add a preliminary check that the buffer is large enough to contain the flatbuffer header before reading the root offset, and ensure the root table position has room for at least a vtable offset.
The FlatBuffer root table offset was only validated when InternalConsistency verification was both requested and compiled in. With Minimal verification (the default), a malicious PTE file could set the root offset to point outside the buffer, causing OOB heap reads. Add a Minimal verification path that validates: - Lower bound: root_offset >= header size (offset + file identifier), preventing the root table from overlapping the header region. - Upper bound: root_offset <= size - sizeof(uoffset_t), ensuring room for at least the vtable offset at the root table position. Also return Error::NotSupported when InternalConsistency verification is requested but compiled out (ET_ENABLE_PROGRAM_VERIFICATION=0), instead of silently continuing with no verification. Addresses TOB-EXECUTORCH-12. This PR was authored with the assistance of Claude.
be5ce97 to
13ba046
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| // Minimal verification: check that the root table offset is within bounds. | ||
| // The first 4 bytes of the flatbuffer contain an offset to the root table. | ||
| ET_CHECK_OR_RETURN_ERROR( | ||
| program_data->size() >= sizeof(flatbuffers::uoffset_t), | ||
| InvalidProgram, | ||
| "Program data size %zu is too small for flatbuffer header", | ||
| program_data->size()); | ||
| uint32_t root_offset = flatbuffers::ReadScalar<flatbuffers::uoffset_t>( |
Summary
Unconditionally verify that the offset is within the flatbuffer bounds. Setting InternalConsistency is a binary size burden (20-30kb), so check this separately when we have minimal verification.
Error out if InternalConsistency is requested, but verification is disabled.
Test plan