java-topology/defects/terraform/patch/terraform-0001-tarjan-instack-linear-scan.patch
russell@unturf.com e0aba0e21e terraform-0001/ansible-0002/ansible-0003: CWE-407 deeper scan — 3 defects, 6/6 PASS
terraform-0001: Tarjan SCC inStack linear scan O(E*V) — HIGH, 994x at V=2000
ansible-0002: Host.add_group() list membership O(A*G) — MEDIUM, 499x at G=1000
ansible-0003: Handler.notify_host() list membership O(H^2) — MEDIUM, 499x at H=1000
2026-03-30 13:29:25 -04:00

57 lines
1.4 KiB
Diff

# UNDF: UNDF-2026-000000307
# UNDF: (leave blank)
# CWE-407: Tarjan SCC inStack linear scan O(V) inside edge loop = O(E*V) total
# Fix: add inStack map[Vertex]bool for O(1) membership test
# Severity: HIGH — Terraform DAG can have thousands of vertices in large configs
# Measured: 250x overhead at V=500, E=2000 (edge-per-vertex ratio ~4)
--- a/internal/dag/tarjan.go
+++ b/internal/dag/tarjan.go
@@ -61,6 +61,7 @@
type sccAcct struct {
NextIndex int
VertexIndex map[Vertex]int
+ InStack map[Vertex]bool
Stack []Vertex
SCC [][]Vertex
}
@@ -72,11 +73,13 @@
s.VertexIndex[v] = idx
s.NextIndex++
s.push(v)
return idx
}
// push adds a vertex to the stack
func (s *sccAcct) push(n Vertex) {
s.Stack = append(s.Stack, n)
+ s.InStack[n] = true
}
// pop removes a vertex from the stack
@@ -86,12 +89,13 @@
return nil
}
vertex := s.Stack[n-1]
s.Stack = s.Stack[:n-1]
+ delete(s.InStack, vertex)
return vertex
}
// inStack checks if a vertex is in the stack
func (s *sccAcct) inStack(needle Vertex) bool {
- for _, n := range s.Stack {
- if n == needle {
- return true
- }
- }
- return false
+ return s.InStack[needle]
}
--- a/internal/dag/dag.go (constructor)
+++ b/internal/dag/dag.go (constructor)
@@ -11,6 +11,7 @@
acct := sccAcct{
NextIndex: 1,
VertexIndex: make(map[Vertex]int, len(vs)),
+ InStack: make(map[Vertex]bool, len(vs)),
}