3.2 KiB
OGRE3D — CWE-407 Disclosure Brief
2026-03-27 · Patch available — awaiting upstream merge
Finding
Three O(n²) defects in OGRE3D's scene management and resource systems. Two involve std::find scans on global collections during scene teardown; one is a reverse-map lookup for ribbon trail chain clearing. Measured up to 10,000× overhead. Patches ready for upstream review.
The Defects
ogre-0001 (PATCHED — HIGH): OgreNode.cpp:75
// msQueuedUpdates: global collection (vector/list)
// Inside Node::~Node() destructor:
auto it = std::find(msQueuedUpdates.begin(), msQueuedUpdates.end(), this);
// O(N) scan per node destruction
std::find performs a linear scan over N queued nodes during each node destructor. During bulk scene teardown with N nodes: O(N²) total. Measured ratio: 5,000×.
ogre-0002 (PATCHED — HIGH): OgreResourceGroupManager.cpp:987
// Inside _notifyAllResourcesRemoved() per bucket:
auto it = std::find(resourceList.begin(), resourceList.end(), resource);
// O(R) per bucket, O(R²) total
std::find scan over R resources per bucket during resource group notification. Measured ratio: 10,000×.
ogre-0003 (PATCHED — HIGH): OgreRibbonTrail.cpp
// chainIndex reverse-map in clearChain():
int idx = chainList.indexOf(chainIndex); // O(N) per chain clear
O(N) reverse-map scan per chain clear. For C chains of size N: O(C × N) total. Measured ratio: 1,000×.
Complexity Proof
ogre-0001: For N=1000 nodes, bulk teardown:
- N destructor calls × O(N)
std::find= O(N²) - At N=1000: 500,000 comparisons vs 1,000 hash lookups
- 5,000× measured ratio.
ogre-0002: For R=1000 resources per bucket:
- O(R²) total across
_notifyAllResourcesRemoved - 10,000× measured ratio.
ogre-0003: 1,000× measured ratio on large ribbon trail scenes.
Impact
All OGRE3D applications performing bulk scene operations: level loading/unloading, scene transitions, resource group unloading, and ribbon trail clearing. OGRE3D is a widely used open-source 3D rendering engine used in games, simulations, and visualization tools. Large scenes with thousands of nodes or resources hit ogre-0001/0002 on every scene change.
The Fix
ogre-0001: Replace msQueuedUpdates vector scan with unordered_set:
// Before
auto it = std::find(msQueuedUpdates.begin(), msQueuedUpdates.end(), this);
if (it != msQueuedUpdates.end()) msQueuedUpdates.erase(it);
// After
// CWE-407 fix: unordered_set for O(1) erase instead of O(N) std::find scan.
msQueuedUpdates.erase(this);
ogre-0002: Pre-build an unordered_set<Resource*> per bucket before scan.
ogre-0003: Add a HashMap<chainIndex, listPosition> reverse map in RibbonTrail.
Patch
defects/ogre/patch/ogre-0001-0002-0003-scene-hashset.patch
What We Ask
- Confirm receipt and assign a GitHub Security Advisory or issue reference.
- Validate the patch against your scene management and resource test suites.
- Assess CVE eligibility — ogre-0002 measured at 10,000× on resource group unload.
- Coordinate a disclosure date — we are targeting 90 days from first contact.
Contact: see cover email. This brief is confidential until coordinated disclosure.