java-topology/whitepaper/outreach/cmake.md

3.9 KiB
Raw Blame History

CMake — CWE-407 Disclosure Brief

2026-03-27 · Patch available — awaiting upstream merge

Finding

Three O(n²) defects in CMake's link dependency computation, runtime DLL tracking, and target source deduplication. All patched. Patches ready for upstream review.

The Defects

cmake-0002 (PATCHED — HIGH): Source/cmComputeLinkDepends.cxx

// GetDirectories() — O(n²) group scan per directory entry:
for (auto const& dir : directories) {
    for (auto const& group : groups) {
        if (group.contains(dir)) { ... }  // O(n) scan per directory per group
    }
}
// O(n²) over all directory-group combinations

GetDirectories() performs O(n²) group scan per directory entry during link dependency computation. Fix: unordered_map<dir, idx>. Measured ratio: 250×.

cmake-0003 (PATCHED — HIGH): Source/cmRuntimeDependencyArchive.cxx

// AddRuntimeDLL() — per DLL addition:
if (std::find(dlls_.begin(), dlls_.end(), dll) == dlls_.end()) {
    dlls_.push_back(dll);  // O(n) duplicate scan per DLL
}
// O(n²) duplicate scan over all DLLs

std::find O(n) scan per DLL in AddRuntimeDLL() dedup. O(n²) total. Fix: unordered_set. Measured ratio: 250×.

cmake-0004 (PATCHED — HIGH): Source/cmTarget.cxx

// AddSource() — per source file addition to target:
if (std::find(sources_.begin(), sources_.end(), source) == sources_.end()) {
    sources_.push_back(source);  // O(n) scan per source per target
}
// O(n²) source dedup per target

std::find O(n) scan per source in AddSource() dedup. O(n²) total per target. Fix: unordered_set. Measured ratio: 500×.

Complexity Proof

cmake-0002: For n directories and n groups:

  • O(n²) — 250× measured ratio.
  • Fixed: unordered_map<dir, idx> → O(n).

cmake-0003: For n=250 DLLs:

  • O(n²) = 31,250 comparisons per build
  • Fixed: unordered_set → O(n)
  • 250× measured ratio.

cmake-0004: For n=500 sources per target:

  • O(n²) = 125,000 comparisons per target
  • Fixed: unordered_set → O(n)
  • 500× measured ratio.

Impact

All CMake users building projects with many link dependencies, runtime DLLs, or large target source lists. cmake-0002 fires during link dependency resolution for every target with many linked directories. cmake-0003 fires during runtime dependency analysis (RUNTIME_DEPENDENCY_SET) for every DLL added. cmake-0004 fires for every target with many source files — extremely common in large C/C++ projects.

CMake is the dominant C/C++ build system. These defects scale quadratically with project size, making large monorepo builds and complex CMake configurations disproportionately affected.

The Fix

cmake-0002: Replace group scan with unordered_map<std::string, size_t> index:

// Before
for (auto const& group : groups) {
    if (group.contains(dir)) { ... }  // O(n) scan

// After
// CWE-407 fix: unordered_map<dir, idx> for O(1) lookup instead of O(n) group scan.
std::unordered_map<std::string, size_t> dirIndex;
// build once, then: dirIndex.find(dir) — O(1)

cmake-0003: Replace std::find with unordered_set for dlls_.

cmake-0004: Replace std::find with unordered_set for sources_.

Patch

defects/cmake/patch/cmake-0002-computelinkdepends-map.patch defects/cmake/patch/cmake-0003-runtimedll-unordered-set.patch defects/cmake/patch/cmake-0004-target-addsource-unordered-set.patch

What We Ask

  1. Confirm receipt and assign a GitLab issue reference (gitlab.kitware.com/cmake/cmake).
  2. Validate the patch against your link dependency, runtime dependency, and target test suites.
  3. Assess CVE eligibility — cmake-0004 fires on every large target build; cmake-0002 on complex multi-library link graphs.
  4. Coordinate a disclosure date — we are targeting 90 days from first contact.

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