undefect. CWE-407 — 92 sites, 42 ecosystems
B&W print-friendly diagrams + tinkerpop-0001 + wave-3 proof sections. Squash of 94 local commits onto remote master.
This commit is contained in:
parent
0a580b313d
commit
db29a08762
1311 changed files with 371202 additions and 1188 deletions
62
defects/saltstack/patch/salt-0001-cloud-has-loop-set.patch
Normal file
62
defects/saltstack/patch/salt-0001-cloud-has-loop-set.patch
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
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
|
||||
Loading…
Add table
Add a link
Reference in a new issue