Skip to content

Harden GLB header and material factor parsing against malformed input - #179

Merged
SergioRZMasson merged 1 commit into
microsoft:masterfrom
SergioRZMasson:sergioze/glb-jsonchunk-overflow-and-material-bounds-master
Jul 30, 2026
Merged

Harden GLB header and material factor parsing against malformed input#179
SergioRZMasson merged 1 commit into
microsoft:masterfrom
SergioRZMasson:sergioze/glb-jsonchunk-overflow-and-material-bounds-master

Conversation

@SergioRZMasson

@SergioRZMasson SergioRZMasson commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

GLBResourceReader::Init computed the GLB header/chunk size checks (GLB_HEADER_BYTE_SIZE + jsonChunkLength, and the component-chunk size sum) in 32-bit arithmetic. A maximal 32-bit JSON chunk length wraps the sum below the real file length, bypassing the "file length covers the header + JSON chunk" guard and letting ReadJson attempt an allocation of up to ~4 GB from a tiny file. Perform these additions in 64-bit (uint64_t) so the sums cannot wrap; the comparisons against the 32-bit file length are unchanged in behavior for all valid files.

ParseMaterial read baseColorFactor[0..3] and emissiveFactor[0..2] by fixed index without checking the parsed element count. When schema validation is disabled by the caller (SchemaFlags::DisableSchemaRoot), a short array leads to an out-of-bounds read past the parsed vector. Validate the element count (4 and 3 respectively) on the core parsing path, independent of schema flags, throwing InvalidGLTFException otherwise.

Adds regression tests: a GLB with a 0xFFFFFFFF JSON chunk length is now rejected, and short baseColorFactor/emissiveFactor arrays are rejected under SchemaFlags::DisableSchemaRoot.

@SergioRZMasson
SergioRZMasson requested a review from bghgary July 30, 2026 17:47
bghgary
bghgary previously approved these changes Jul 30, 2026
…array lengths

GLBResourceReader::Init computed the GLB header/chunk size checks
(GLB_HEADER_BYTE_SIZE + jsonChunkLength, and the component-chunk size sum) using
32-bit arithmetic. For a large 32-bit JSON chunk length the addition can wrap,
producing a value smaller than the actual file length so the size check passes
incorrectly and ReadJson is then asked for a very large allocation. Perform these
additions in 64-bit (uint64_t) so the sums cannot wrap; the comparisons against
the 32-bit file length are unchanged in behavior for all valid files.

ParseMaterial read baseColorFactor[0..3] and emissiveFactor[0..2] by fixed index
without checking how many elements were parsed. When the caller disables schema
validation (SchemaFlags::DisableSchemaRoot), a shorter array would be read beyond
the elements that were provided. Validate the element count (4 and 3 respectively)
on the core parsing path, independent of schema flags, throwing InvalidGLTFException
otherwise.

Adds regression tests: a GLB with a 0xFFFFFFFF JSON chunk length is now rejected,
and short baseColorFactor/emissiveFactor arrays are rejected under
SchemaFlags::DisableSchemaRoot.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 039828de-4db2-48f8-a5de-c9f7d33baffa
@SergioRZMasson
SergioRZMasson force-pushed the sergioze/glb-jsonchunk-overflow-and-material-bounds-master branch from c57c8b3 to abd64de Compare July 30, 2026 18:15
@SergioRZMasson
SergioRZMasson merged commit 3c37a3c into microsoft:master Jul 30, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants