B&W print-friendly diagrams + tinkerpop-0001 + wave-3 proof sections. Squash of 94 local commits onto remote master.
62 lines
2.5 KiB
Diff
62 lines
2.5 KiB
Diff
From: agent-blackops <blackops@unturf.com>
|
||
Date: Thu, 26 Mar 2026 00:00:00 +0000
|
||
Subject: [PATCH] cloud: replace _has_loop seen-list with set for O(1) membership
|
||
|
||
CWE-407: Algorithmic complexity via O(depth) list membership test and
|
||
O(depth) list copy at every recursion level in _has_loop().
|
||
|
||
seen is a plain Python list. At each recursive call:
|
||
- `if dep not in seen` performs a linear scan — O(depth)
|
||
- `list(seen)` copies the entire list — O(depth)
|
||
|
||
For a dependency graph with V machines each having D requires entries the
|
||
total work is O(V × D × depth²), which degenerates to O(V³) for a linear
|
||
chain.
|
||
|
||
Fix: change seen to a set (machine name strings are hashable).
|
||
`val in seen` becomes O(1) amortised. `set(seen)` copy is still O(depth)
|
||
but avoids the per-element equality scan, and is semantically equivalent.
|
||
The structural logic and recursion pattern are unchanged.
|
||
|
||
Defect-Id: SALT-001
|
||
Severity: MEDIUM
|
||
CWE: CWE-407 (Inefficient Algorithmic Complexity)
|
||
---
|
||
salt/cloud/__init__.py | 10 ++++------
|
||
1 file changed, 4 insertions(+), 6 deletions(-)
|
||
|
||
diff --git a/salt/cloud/__init__.py b/salt/cloud/__init__.py
|
||
index xxxxxxx..yyyyyyy 100644
|
||
--- a/salt/cloud/__init__.py
|
||
+++ b/salt/cloud/__init__.py
|
||
@@ -1830,8 +1830,8 @@ class Map(CloudClient):
|
||
def _has_loop(self, dmap, seen=None, val=None):
|
||
if seen is None:
|
||
for values in dmap["create"].values():
|
||
- seen = []
|
||
+ seen = set() # CWE-407 fix: set for O(1) membership test
|
||
try:
|
||
machines = values["requires"]
|
||
except KeyError:
|
||
machines = []
|
||
for machine in machines:
|
||
- if self._has_loop(dmap, seen=list(seen), val=machine):
|
||
+ if self._has_loop(dmap, seen=set(seen), val=machine): # CWE-407 fix
|
||
return True
|
||
else:
|
||
- if val in seen:
|
||
+ if val in seen: # CWE-407 fix: O(1) set lookup (was O(depth) list scan)
|
||
return True
|
||
|
||
- seen.append(val)
|
||
+ seen.add(val) # CWE-407 fix: set.add replaces list.append
|
||
try:
|
||
machines = dmap["create"][val]["requires"]
|
||
except KeyError:
|
||
machines = []
|
||
|
||
for machine in machines:
|
||
- if self._has_loop(dmap, seen=list(seen), val=machine):
|
||
+ if self._has_loop(dmap, seen=set(seen), val=machine): # CWE-407 fix
|
||
return True
|
||
return False
|