grafana: 3 CWE-407 defects; loki: 1 CWE-407 defect; 4/4 PASS
grafana-0001: getDashboardsSharedWithUser dashboard UID dedup O(P^2) MEDIUM 2.5x grafana-0002: folder UID dedup slices.Contains O(P^2) 4 sites MEDIUM 4x grafana-0003: deduplicateAvailableFolders ContainsFunc O(F*A) MEDIUM 9.3x loki-0001: DAG AddEdge/Eliminate slices.Contains O(E^2) LOW 2.1x
This commit is contained in:
parent
cf2c734de1
commit
689ec25d05
6 changed files with 577 additions and 66 deletions
54
defects/loki/patch/loki-0001-dag-edge-dedup.patch
Normal file
54
defects/loki/patch/loki-0001-dag-edge-dedup.patch
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
# UNDF: (leave blank)
|
||||
# CWE-407: DAG AddEdge/Eliminate slices.Contains on children/parents O(E^2)
|
||||
# File: pkg/engine/internal/util/dag/dag.go
|
||||
# Severity: LOW
|
||||
# Ratio: ~250x at E=500 edges per node (synthetic; practical fan-out is small)
|
||||
#
|
||||
# Graph.AddEdge checks slices.Contains(g.children[e.Parent], e.Child)
|
||||
# and slices.Contains(g.parents[e.Child], e.Parent) to enforce edge
|
||||
# uniqueness. If a node accumulates E children, each new AddEdge scans
|
||||
# the entire children slice, making bulk insertion O(E^2).
|
||||
#
|
||||
# Graph.Eliminate has nested loops: for each parent, for each child of
|
||||
# the eliminated node, slices.Contains(g.children[parent], child)
|
||||
# scans the parent's children list. Similarly for the parents list.
|
||||
#
|
||||
# In Loki's query planner, node fan-out is typically 1-3, so this is
|
||||
# LOW severity in practice. The fix converts children/parents to
|
||||
# map[NodeType]struct{} adjacency sets for O(1) membership.
|
||||
#
|
||||
# Note: changing []NodeType to map[NodeType]struct{} changes iteration
|
||||
# order. The current code preserves insertion order via slices. A
|
||||
# minimal fix would keep the slice for ordering but add a parallel set
|
||||
# for membership checks.
|
||||
--- a/pkg/engine/internal/util/dag/dag.go
|
||||
+++ b/pkg/engine/internal/util/dag/dag.go
|
||||
@@ -29,8 +29,10 @@ type Graph[NodeType Node] struct {
|
||||
nodes nodeSet[NodeType]
|
||||
- parents map[NodeType][]NodeType
|
||||
- children map[NodeType][]NodeType
|
||||
+ parents map[NodeType][]NodeType
|
||||
+ children map[NodeType][]NodeType
|
||||
+ parentSet map[NodeType]map[NodeType]struct{}
|
||||
+ childrenSet map[NodeType]map[NodeType]struct{}
|
||||
}
|
||||
|
||||
@@ -95,10 +97,16 @@ func (g *Graph[NodeType]) AddEdge(e Edge[NodeType]) error {
|
||||
|
||||
// Uniquely add the edges.
|
||||
- if !slices.Contains(g.children[e.Parent], e.Child) {
|
||||
+ if g.childrenSet[e.Parent] == nil {
|
||||
+ g.childrenSet[e.Parent] = make(map[NodeType]struct{})
|
||||
+ }
|
||||
+ if _, exists := g.childrenSet[e.Parent][e.Child]; !exists {
|
||||
+ g.childrenSet[e.Parent][e.Child] = struct{}{}
|
||||
g.children[e.Parent] = append(g.children[e.Parent], e.Child)
|
||||
}
|
||||
- if !slices.Contains(g.parents[e.Child], e.Parent) {
|
||||
+ if g.parentSet[e.Child] == nil {
|
||||
+ g.parentSet[e.Child] = make(map[NodeType]struct{})
|
||||
+ }
|
||||
+ if _, exists := g.parentSet[e.Child][e.Parent]; !exists {
|
||||
+ g.parentSet[e.Child][e.Parent] = struct{}{}
|
||||
g.parents[e.Child] = append(g.parents[e.Child], e.Parent)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue