2.9 KiB
SPIRV-Cross — CWE-407 Disclosure Brief
2026-03-27 · Patch available — awaiting upstream merge
Finding
Two O(n²) defects in SPIRV-Cross's shader reflection and GLSL backend. One uses O(n²) implied-read vector scans at 7 sites; the other uses O(n²) visited vector scans in CFG block traversal at 6 sites. Patches ready for upstream review.
The Defects
spirv-cross-0001 (PATCHED — HIGH): spirv_cross.cpp (7 sites)
// Implied-read variable scan — per variable, 7 sites:
auto it = std::find(implied_read_variables.begin(),
implied_read_variables.end(), var);
// O(n²) implied-read dedup across 7 sites
std::find O(n) scan on implied_read_variables vector for every variable at 7 sites. O(n²) total. 7 sites affected.
spirv-cross-0002 (PATCHED — HIGH): spirv_glsl.cpp (6 sites)
// visit_branch() — visited set as std::vector:
if (std::find(visited.begin(), visited.end(), block_id) == visited.end()) {
visited.push_back(block_id);
// recurse
}
// O(n²) CFG traversal across 6 sites
std::find on visited vector O(n²) per CFG traversal at 6 sites. 6 sites affected.
Complexity Proof
spirv-cross-0001: For n variables at 7 sites:
- O(n²) implied-read dedup
- Fixed:
unordered_set<uint32_t>→ O(n) at all 7 sites.
spirv-cross-0002: For n CFG blocks at 6 sites:
- O(n²) per traversal
- Fixed:
unordered_set<uint32_t>visited → O(n) per traversal at all 6 sites.
Impact
All SPIRV-Cross users compiling SPIR-V shaders to GLSL, HLSL, MSL, or other targets. SPIRV-Cross is used by game engines (Unity, Unreal Engine, Godot), Vulkan applications, and GPU compute frameworks. Shader compilation runs on every new shader variant. Complex shaders with many variables and deep CFGs hit both defects during compilation. Both defects are compile-time — they degrade shader compilation speed and increase build times.
The Fix
spirv-cross-0001: Replace implied_read_variables vector with unordered_set<uint32_t> at all 7 sites.
spirv-cross-0002: Replace visited vector with unordered_set<uint32_t> in visit_branch() at all 6 sites:
// Before
if (std::find(visited.begin(), visited.end(), block_id) == visited.end()) {
visited.push_back(block_id);
}
// After
// CWE-407 fix: unordered_set for O(1) visited check instead of O(n) std::find scan.
if (visited.insert(block_id).second) {
// was newly inserted — recurse
}
Patch
defects/spirv-cross/patch/spirv-cross-0001-0002-unordered-set.patch
What We Ask
- Confirm receipt and assign a GitHub Security Advisory or issue reference.
- Validate the patch against your shader compilation and CFG traversal test suite.
- Assess CVE eligibility — O(n²) shader compilation overhead at 13 sites total.
- Coordinate a disclosure date — we are targeting 90 days from first contact.
Contact: see cover email. This brief is confidential until coordinated disclosure.