How the bug was found.
.glb reaches both Microsoft Word and the Microsoft 3D Viewer. The two products share their 3D parsing code at the assembly level.I found this bug several years ago and never published the technical story. This page reconstructs the research from the original fuzzer, the GLB samples it generated, the WinDbg logs, the rendering screenshots, and the disclosure correspondence I still have on disk. The bug was eventually published by Microsoft on June 9, 2020 as the Microsoft Office Remote Code Execution Vulnerability.
Microsoft Office added the ability to insert 3D models into Word, PowerPoint, and Excel documents around 2018. Under the hood, the rendering and parsing path goes through a relatively young engine that is also packaged as a standalone Windows 10 app, the Microsoft 3D Viewer. Two separate binaries - MSOSPECTRE.DLL in Office and Mira.Core.Engine.UWP.dll in 3D Viewer - share parser code at the assembly level. One malformed model can crash both.
The format itself is binary glTF: a 12-byte header, a JSON chunk, an optional BIN chunk. The JSON describes a scene graph in which almost every field is an integer index into another field. scenes reference nodes; nodes reference meshes; meshes reference accessors; accessors reference bufferViews; bufferViews reference buffers. Animations layer in samplers and channels on top. The complexity is the cross-references the parser is expected to keep consistent.
That is where grammar fuzzers earn their keep. Mutational fuzzers tend to break the references and bounce off the parser's "is this even a valid index?" early-exit checks. A grammar that respects the references but deliberately breaks the agreements between them - two accessors sharing a bufferView but disagreeing about how many elements live there - lands deeper in the parser, where arithmetic mistakes are more likely to matter. That made the target attractive: a real parser, a complex indexed format, and a path into Word documents.
How the bucket stood out
The interesting bucket showed up before the MSRC report went out on January 30, 2020. The exact samples attached to that report are no longer in this working folder. The earliest crashing GLB I still have on disk is from February 10, 2020, with additional continued-analysis variants captured around February 23 and 25.
Two things made the bucket stand out from typical Office crashes.
First, the variants in this bucket all landed on the same low-level instruction - rep movs inside VCRUNTIME140!memcpy_repmovs (or its _APP variant in 3D Viewer) - but the surrounding stacks varied with which mesh attribute the parser was setting: Mesh::SetPositions, Mesh::SetIndices, Mesh::SetUV0, Mesh::SetUV1, Mesh::SetColours, Mesh::SetJointData. That is the signature of a single arithmetic mistake in a shared upstream helper, fanned out into many sinks.
Second, the same input crashed both products at matching call-site offsets. The bug was in the shared parser, not in either application's glue. The samples in this bucket reproduced the same crash pattern in both products: winword.exe driven through gfx!Gfx::IModel3DScene::* and mso20win32client ordinals into MSOSPECTRE.DLL, and 3DViewer.exe driven through Mira.Core.Engine.UWP.dll. The shared-code reachability is what made the bug interesting beyond a one-off parser crash.
r14 is computed from one attacker-controlled field while the underlying buffer is sized from another.Under PageHeap, a db rsi - 0x50 against the canonical sample shows the source pointer walking into uncommitted memory while the loop is still iterating; the bytes immediately past the readable range come back as ??. The crash signature is an out-of-bounds read driven by a length the parser trusts from JSON.

