# 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`

```cpp
// 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`

```cpp
// 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`

```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`:

```cpp
// 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.
