Batch 9 (15): bun, bzflag (3), cake_wallet (4), calligra, caprice32 (2), cataclysm (3), cemu Batch 10 (15): cemu-0002, citra, clickhouse-java, cmake (3), cocos2d (3), conduit, cura (2), curaengine, clamav, contiki
3 KiB
Cemu — CWE-407 Disclosure Brief (cemu-0001)
2026-04-14 · Patch available — awaiting upstream merge
Finding
One O(n²) defect in Cemu's Vulkan texture view system. The LatteTextureViewVk::AddDescriptorSetReference() method uses std::find on a std::vector for dedup before inserting descriptor set references. Fires during Vulkan rendering when texture views get bound to descriptor sets.
The Defect
cemu-0001 (PATCHED — HIGH): src/Cafe/HW/Latte/Renderer/Vulkan/LatteTextureViewVk.h:22
// In LatteTextureViewVk — fires per descriptor set binding:
void AddDescriptorSetReference(struct VkDescriptorSetInfo* dsInfo) {
if (std::find(list_descriptorSets.begin(), list_descriptorSets.end(), dsInfo)
== list_descriptorSets.end())
list_descriptorSets.emplace_back(dsInfo);
};
list_descriptorSets is a std::vector<VkDescriptorSetInfo*>. Every time a texture view gets bound to a descriptor set, the code scans the growing vector to check for duplicates. Games with many active textures and frequent descriptor set rebinding accumulate large reference lists, making the linear scan costly.
Complexity Proof
At D=200 descriptor set references per texture view:
- Defective: 200 insertions × average 100 comparisons = ~20,000 pointer comparisons
- Fixed: 200 insertions × O(1) = 200 hash lookups
- ~100× op reduction. Fires during rendering for every texture bind.
Impact
Cemu emulates the Wii U. Wii U games with complex rendering pipelines (Breath of the Wild, Mario Kart 8, Xenoblade Chronicles X) use many textures with frequent descriptor set rebinding. The quadratic cost adds per-frame overhead that scales with scene complexity.
The Fix
Replace std::vector with std::unordered_set:
// Before
std::vector<struct VkDescriptorSetInfo*> list_descriptorSets;
void AddDescriptorSetReference(struct VkDescriptorSetInfo* dsInfo) {
if (std::find(list_descriptorSets.begin(), list_descriptorSets.end(), dsInfo)
== list_descriptorSets.end())
list_descriptorSets.emplace_back(dsInfo);
};
// After
// CWE-407 fix: unordered_set for O(1) dedup instead of O(D) vector scan.
std::unordered_set<struct VkDescriptorSetInfo*> list_descriptorSets;
void AddDescriptorSetReference(struct VkDescriptorSetInfo* dsInfo) {
list_descriptorSets.insert(dsInfo);
};
Patch
Fix available: defects/cemu-0001/patch/cemu-0001.patch
Two-file patch across LatteTextureViewVk.h and LatteTextureViewVk.cpp. Replaces std::vector with std::unordered_set for descriptor set references. Updates destructor to iterate the set.
What We Ask
A patch is ready for review.
- Confirm receipt and assign a GitHub issue reference (cemu-project/Cemu).
- Assess severity — fires per texture bind during Vulkan rendering.
- Coordinate a disclosure date — we target 90 days from first contact.
- We will credit the Cemu team in the public disclosure. Preferred acknowledgment format welcome.
Contact: see cover email. This brief is confidential until coordinated disclosure.