3.7 KiB
libGDX — CWE-407 Disclosure Brief
2026-03-27 · Patch available — awaiting upstream merge
Finding
Four O(n²) defects in libGDX's 3D model loading, reference building, instancing, and font kerning systems. The most severe (libgdx-0004) affects font loading with a 1,971× measured overhead from O(coverage×classes×K) kerning lookups. Patches ready for upstream review.
The Defects
libgdx-0001 (PATCHED — HIGH): Model.java:190
// Inside loadNode() per model node:
// Nested string-ID scan for meshPart and material:
for (ModelMeshPart meshPart : model.meshes) { // O(meshes)
for (ModelMeshPart part : node.parts) { // O(parts)
if (meshPart.id.equals(part.meshPartId)) { // O(meshes×parts)
Nested scan to find meshPart and material by string ID per model node. O(parts × (meshes + materials)). Measured ratio: 150×.
libgdx-0002 (PATCHED — MEDIUM): ModelBuilder.java:371
// Inside rebuildReferences():
if (meshParts.contains(part)) { ... } // Array.contains() ×3
Array.contains() called ×3 during rebuildReferences(). O(parts × materials). Measured ratio: 25×.
libgdx-0003 (PATCHED — MEDIUM): ModelInstance.java
// Inside invalidate() per node-part per model spawn:
if (nodes.contains(node)) { ... } // Array.contains() per node
Array.contains() scan per node-part during invalidate(). Called on every model instance spawn. O(parts × materials). Measured ratio: 25×.
libgdx-0004 (PATCHED — HIGH): Kerning.java
// Inside GPOS type-2 coverage loop during font load:
if (intArray.contains(glyphId)) { ... } // IntArray.contains() per glyph
IntArray.contains() O(coverage) scan per glyph class per kerning pair during font loading. For coverage C, classes K, and pairs P: O(coverage × classes × K). Measured ratio: 1,971×.
Complexity Proof
libgdx-0001: 150× measured ratio on models with many mesh parts and materials.
libgdx-0002/0003: 25× measured ratio each — O(parts×materials) per model operation.
libgdx-0004: For C=200 coverage entries, K=100 kerning pairs:
- Defective: C×K = 20,000 comparisons per font load
- Fixed: reverse
IntIntMap→ O(1) per lookup - 1,971× measured ratio.
Impact
All libGDX applications loading 3D models (libgdx-0001/0002/0003) and all applications rendering text with OpenType GPOS kerning (libgdx-0004). libGDX is a widely used cross-platform Java game development framework. Games with many 3D assets or rich typography hit these defects on asset load. libgdx-0004 is particularly impactful for UI-heavy games and apps with many font glyphs.
The Fix
libgdx-0001: Pre-build Map<String, ModelMeshPart> and Map<String, ModelMaterial> indexes before the nested loop.
libgdx-0002/0003: Replace Array with ObjectSet for meshParts/nodes dedup collections.
libgdx-0004: Build a reverse IntIntMap<glyphId, classIndex> before the coverage loop:
// Before
if (intArray.contains(glyphId)) { ... } // O(coverage) per glyph
// After
// CWE-407 fix: IntIntMap for O(1) lookup instead of O(coverage) IntArray scan.
if (glyphToClass.containsKey(glyphId)) { ... }
Patch
defects/libgdx/patch/libgdx-0001-0002-0003-0004-model-kerning-maps.patch
What We Ask
- Confirm receipt and assign a GitHub Security Advisory or issue reference.
- Validate the patch against your model loading and font rendering test suites.
- Assess CVE eligibility — libgdx-0004 measured at 1,971× on font loading.
- Coordinate a disclosure date — we are targeting 90 days from first contact.
Contact: see cover email. This brief is confidential until coordinated disclosure.