java-topology/whitepaper/outreach/ogre.md

3.2 KiB
Raw Blame History

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

  1. Confirm receipt and assign a GitHub Security Advisory or issue reference.
  2. Validate the patch against your scene management and resource test suites.
  3. Assess CVE eligibility — ogre-0002 measured at 10,000× on resource group unload.
  4. Coordinate a disclosure date — we are targeting 90 days from first contact.

Contact: see cover email. This brief is confidential until coordinated disclosure.