java-topology/whitepaper/outreach/xonotic-0002.md
russell@unturf.com 6784cdf1cf feat: add 39 outreach docs (batches 6-8)
Batch 6 (9): dolibarr, jitsi-videobridge, zed, tryton, suricata,
  strawberry, zulip, zesarux, zephyr
Batch 7 (15): xonotic (4), xash3d (3), xenia, xtuple, zabbix (2),
  zathura, zebra, yabause, zephyr-0001
Batch 8 (15): woodpecker (2), wine (4), widelands (3), wesnoth (3),
  wekan (3)

Mix of CWE-407 and CWE-312.
2026-04-14 17:06:28 -04:00

2.5 KiB
Raw Blame History

Xonotic (DarkPlaces) — CWE-407 Disclosure Brief (xonotic-0002)

2026-04-13 · Patch available — awaiting upstream merge

Finding

One O(M²) defect in DarkPlaces server model precaching. SV_ModelIndex performs a linear scan of model_precache[] on every model reference, making total cost O(M²) during map load where M = number of precached models.

The Defect

xonotic-0002 (PATCHED — MEDIUM): sv_main.c:1420

// In SV_ModelIndex() — fires per model precache:
for (i = 2; i < limit; i++)
{
    if (!sv.model_precache[i][0]) { /* empty slot — insert */ }
    if (!strcmp(sv.model_precache[i], filename))
        return i;
}

model_precache[] holds up to MAX_MODELS entries. Each call to SV_ModelIndex scans the entire array via strcmp to check for duplicates. During map load, the engine precaches all models sequentially, producing O(1+2+...+M) = O(M²/2) total comparisons.

Complexity Proof

At M=500 precached models:

  • Defective: 500 × 250 average = 125,000 string comparisons during map load
  • Fixed: 500 × O(1) hash lookups = 500 operations
  • ~250x op reduction per map load.

Impact

Xonotic servers precache hundreds of models per map. Every map change on a multiplayer server pays this cost. Mods that add custom player models, weapons, or map objects increase M and worsen the quadratic scaling. Dedicated servers running map rotations accumulate this overhead on every level transition.

The Fix

Add a static hash table (sv_model_precache_hashtable[512] + chain array) for O(1) average lookup:

// Before
for (i = 2; i < limit; i++)
    if (!strcmp(sv.model_precache[i], filename)) return i;

// After
// CWE-407 fix: hash table for O(1) precache lookup.
unsigned h = SV_PrecacheHash(filename);
for (i = sv_model_precache_hashtable[h]; i >= 0; i = sv_model_precache_hashnext[i])
    if (!strcmp(sv.model_precache[i], filename)) return i;

Patch

Fix available: defects/xonotic-0002/patch/xonotic-0002.patch

Single-file patch on sv_main.c. Adds hash table and hash function for model precache dedup.

What We Ask

A patch is ready for review.

  1. Confirm receipt and assign a GitHub issue reference (xonotic/darkplaces).
  2. Assess severity — fires during every map load, quadratic in model count.
  3. Coordinate a disclosure date — we target 90 days from first contact.
  4. We will credit the Xonotic/DarkPlaces team in the public disclosure. Preferred acknowledgment format welcome.

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