3.9 KiB
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
- Confirm receipt and assign a GitLab issue reference (gitlab.kitware.com/cmake/cmake).
- Validate the patch against your link dependency, runtime dependency, and target test suites.
- Assess CVE eligibility — cmake-0004 fires on every large target build; cmake-0002 on complex multi-library link graphs.
- Coordinate a disclosure date — we are targeting 90 days from first contact.
Contact: see cover email. This brief is confidential until coordinated disclosure.