java-topology/whitepaper/outreach/wine-0001.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.9 KiB
Raw Permalink Blame History

Wine — CWE-407 Disclosure Brief (wine-0001)

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

Finding

One O(n²) defect in Wine's NT DLL loader. The dependency deduplication function find_module_dependency performs an O(D) linear scan through a circular singly-linked list of dependencies. Called from add_module_dependency_after on every DLL import, this produces O(I×D) cost per module where I = imports and D = accumulated dependencies.

The Defect

wine-0001 (PATCHED — HIGH): dlls/ntdll/loader.c:860

// find_module_dependency — fires on every DLL import:
static LDR_DEPENDENCY *find_module_dependency(LDR_DDAG_NODE *from, LDR_DDAG_NODE *to)
{
    SINGLE_LIST_ENTRY *entry, *mark = from->Dependencies.Tail;
    if (!mark) return NULL;
    for (entry = mark->Next; entry != mark; entry = entry->Next)
    {
        LDR_DEPENDENCY *dep = CONTAINING_RECORD(entry, LDR_DEPENDENCY, dependency_to_entry);
        if (dep->dependency_to == to && dep->dependency_from == from) return dep;
    }
    return NULL;
}

For complex DLL trees with hundreds of imports, each new import scans all previously accumulated dependencies. Applications loading large dependency trees (Visual Studio, .NET runtime, complex Win32 applications) pay quadratic cost at startup.

Complexity Proof

At I=200 imports, D growing to 200:

  • Defective: 1 + 2 + 3 + ... + 200 = ~20,000 linked-list traversals
  • Fixed: 200 hash lookups = 200 operations
  • ~100× op reduction per module load.

Impact

Wine runs Windows applications on Linux, macOS, and Android. Every Wine process loads DLLs through this path. Applications with deep dependency trees (IDE suites, game launchers, .NET applications) pay quadratic cost on every startup. Steam Deck and Proton users running complex games hit this on every launch.

The Fix

Maintain a hash set (e.g., wine_rb_tree keyed on dependency_to pointer) alongside the linked list for O(1) dedup. The linked list must stay for Windows ABI compatibility:

// Before: O(D) linear scan through circular linked list
for (entry = mark->Next; entry != mark; entry = entry->Next) { ... }

// After: O(1) hash/tree lookup, linked list preserved for ABI
// wine_rb_tree or open-addressed hash table keyed on dependency_to pointer

Patch

Fix available: defects/wine-0001/patch/wine-0001-loader-dependency-dedup.patch

Single-file patch in dlls/ntdll/loader.c. Adds O(1) lookup alongside the existing linked-list structure.

What We Ask

A patch is ready for review.

  1. Confirm receipt and assign a reference on the Wine Bugzilla or GitLab (wine/wine).
  2. Assess severity — fires on every DLL import during process initialization.
  3. Coordinate a disclosure date — we target 90 days from first contact.
  4. We will credit the Wine team in the public disclosure. Preferred acknowledgment format welcome.

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