draco: OOB read/SEGV in glTF animation channel and sampler indices (unchecked indices in AddChannelToAnimation/AddSamplerToAnimation)

Aperta
#1,261 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

@Subhan1794 ci sta già lavorando.

Dal 23/10/2026.

  • #1262 di @Subhan1794 — aperta

Valutazione

Difficoltà
2/5
Tempo stimato
1-3 ore
Idoneità per principianti
20/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Ferma
Stack tecnologico
cpp

Direzione di ricerca

Read src/draco/io/tiny_gltf_utils.cc, especially AddChannelToAnimation and AddSamplerToAnimation, and compare the existing inverseBindMatrices bounds check in gltf_decoder.cc. The issue reports crashes for out-of-range channel.sampler, sampler.input, and sampler.output indices; verify those cases reject invalid indices before vector access. Done means the invalid animation inputs are rejected safely while the valid animation control still decodes; linked pull request #1262 is already open.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Root cause: the glTF animation path indexes model vectors with attacker-controlled indices and no bounds check. In src/draco/io/tiny_gltf_utils.cc, AddChannelToAnimation reads input_animation.samplers[channel.sampler] directly, and AddSamplerToAnimation reads model.accessors[sampler.input] and model.accessors[sampler.output] directly. The vendored tinygltf parser only checks that these fields are present integers — it never validates their range — so a crafted value flows straight into operator[]. Reachable via the public scene path: DecodeFromFileToScene -> DecodeGltfToScene -> AddAnimationsToScene -> AddChannelToAnimation -> AddSamplerToAnimation. Contrast: skin inverseBindMatrices IS guarded (gltf_decoder.cc checks against accessors.size()), and primitive attributes/indices are guarded — the animation path was missed.

Evidence (local ASan+UBSan build, scene decode path, valid animation control decodes clean):

  • Valid control (sampler 0, input 0, output 0): decodes ok.
  • channel.sampler = 5 with only 1 sampler: ASan heap-buffer-overflow READ size 4 (the wild sampler object read then faults downstream — one unchecked chain, one fix covers both).
  • sampler.input = 999: ASan SEGV READ.
  • sampler.output = 999: ASan SEGV READ.
  • channel.sampler = -1 and sampler.input = -1: ASan SEGV READ.
  • No WRITE found in any case.

Impact: crash (denial of service) in any tool decoding glTF scenes with animations through this path. Low severity.

Suggested fix: range checks on channel.sampler, sampler.input, and sampler.output mirroring the existing skin guard, rejecting out-of-range indices before indexing.

Note: distinct from #1247, which covers bufferView/buffer and accessor indices on the primitive path — this is a different function/file/path (animation).

Reproducer: the minimal glTF triggers are available on request.

Lingua principale
C++
Stelle
7.5k
Fork
1.1k
Merge medio
23h 57m
PR unite (30g)
3

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di google/draco

Tutte le issue di google/draco

Issue simili

Altre issue su C++

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.