Skip to content

gltfio: EXT_meshopt_compression indices bypass cgltf validation → OOB index read #10193

Description

@adilburaksen

cgltf_validate bounds-checks primitive index values against the vertex count, but for an EXT_meshopt_compression bufferView it validates the fallback buffer bytes, not the decoded stream. cgltf_calc_index_bound reads buffer_view->buffer->data + offset (fallback bytes), while the real indices live in a separate compressed stream decoded later.

Filament decodes it in decodeMeshoptCompression (libs/gltfio/src/Utility.cpp:~90), which sets buffer_view->data = <decoded> after validation:

ResourceLoader::loadResources:
  loadCgltfBuffers(...)          // cgltf_load_buffers + cgltf_validate  (checks FALLBACK bytes)
  decodeMeshoptCompression(...)  // meshopt_decodeIndexBuffer -> real indices (NO re-validation)

So an attacker crafts a file whose fallback index region is valid (validation passes) but the meshopt-compressed stream decodes to indices >= vertexCount. After decode, cgltf_accessor_read_index returns OOB values that nothing re-checks. Confirmed at the cgltf/meshopt level with ASan.

Impact: OOB index read from an untrusted .glb on load.

Suggested fix: re-validate decoded meshopt index buffers against the vertex count after decodeMeshoptCompression. I previously opened PR #10175 with this fix; it was auto-closed (maintainer-only directory), so filing here as requested.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions