google / google/filament

Heap out-of-bounds read in gltfio animation playback

Open
#10,138 0 comments 0 reactions 1 assignee View on GitHub

@poweifeng is already working on this.

Since Jul 6, 2026.

gltf security
Dominant language
C++
Stars
20.5k
Forks
2.3k
Avg merge
2d 13h
Merged PRs (30d)
90

Description

Describe the bug
gltfio accepts malformed glTF animation data where a sampler output accessor type does not match the channel target path.

  • createSampler() allocates the animation value buffer based on the sampler output accessor type. For a SCALAR output, it allocates one float per keyframe. Later, AnimatorImpl::applyAnimation() reads the
  • same buffer based on the channel target path. A translation channel is read as float3.
  • validateAnimation() only checks keyframe counts, so a translation channel with a SCALAR output accessor can be accepted. Playback then reads past the end of the scalar-sized heap buffer.

To Reproduce
Steps to reproduce the behavior:

  1. Build Filament with AddressSanitizer enabled.
  2. Load a GLB/glTF asset containing an animation channel with:
    • target path: translation
    • sampler output accessor type: SCALAR
    • matching input/output accessor counts
  3. Call Animator::applyAnimation() for the accepted animation.

Expected behavior
The malformed animation should be rejected during validation. Translation and scale channels should require VEC3 outputs, rotation should require VEC4, and weights should require SCALAR.

Screenshots
Not applicable.

Logs

animationCount=1
=================================================================
==2008772==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x502000004020
READ of size 4 at 0x502000004020 thread T0

#3 0x65118068b345 in filament::gltfio::AnimatorImpl::applyAnimation(...) /tmp/poc/filament/libs/gltfio/src/Animator.cpp:472:67
#4 0x65118068901a in filament::gltfio::Animator::applyAnimation(...) /tmp/poc/filament/libs/gltfio/src/Animator.cpp:308:16
#5 0x65117fc68f8f in main /tmp/poc/filament/proof/poc/example.cpp:80:19

0x502000004020 is located 0 bytes after 16-byte region [0x502000004010,0x502000004020)
allocated by thread T0 here:

#7 0x651180694e9f in std::__1::vector<float, std::__1::allocator<float>>::resize(unsigned long)
#8 0x651180685f38 in filament::gltfio::createSampler(...) /tmp/poc/filament/libs/gltfio/src/Animator.cpp:111:24
#9 0x651180683b38 in filament::gltfio::Animator::Animator(...) /tmp/poc/filament/libs/gltfio/src/Animator.cpp:223:13

SUMMARY: AddressSanitizer: heap-buffer-overflow
==2008772==ABORTING

Desktop:

  • OS: Ubuntu 24.04.4 LTS, x86_64
  • GPU: Not GPU-dependent
  • Backend: Noop backend
  • Compiler: clang 18.1.3

Smartphone:
Not applicable.

Additional context
The issue is in libs/gltfio/src/Animator.cpp.
The fix is to extend validateAnimation() so sampler->output->type must match channel.target_path before importing the animation:

  • translation / scale -> cgltf_type_vec3
  • rotation -> cgltf_type_vec4
  • weights -> cgltf_type_scalar
  • invalid paths -> reject

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.