infra-cluster: consul/helm/doris CWE-407 scan; buildkit/containerd/traefik/grafana/victoria-metrics/nifi/samza CLEAN

consul-0001: makeMeshGatewayPeerFilterChain peerNames O(S×B×P) slice scan → map[string]struct{}
helm-0001: ResourceList.Difference/Intersect O(N²) via Contains → pre-built map index
doris-0001: EquivalenceClass.getEquivalenceSetList ArrayList visited O(V²) → IdentityHashMap
doris-0002: PlanNode.addConjunct ArrayList.contains O(C²) → LinkedHashSet

6 CLEAN: buildkit, containerd, traefik, grafana, victoria-metrics, nifi (except pre-existing 0001), samza
This commit is contained in:
russell@unturf.com 2026-03-29 19:54:13 -04:00
parent cfed6f1c5b
commit 5b5355cb07
11 changed files with 479 additions and 50 deletions

View file

@ -0,0 +1,94 @@
# UNDF: UNDF-2026-000000090
# UNDF: (pending)
# consul-0001: makeMeshGatewayPeerFilterChain — peerNames O(S×B×P) slice lookup
## CWE-407 — Algorithmic Complexity
| Field | Value |
|-------|-------|
| ID | consul-0001 |
| Severity | MEDIUM |
| Ecosystem | consul |
| Package | agent/xds |
| File | `agent/xds/listeners.go` |
| Lines | 2282–2286 |
| Complexity | O(S×B×P) — services × bundles × peers per service |
| Hot path | Mesh gateway listener rebuild on every topology change |
## Defect
`makeMeshGatewayPeerFilterChain` receives `peerNames []string` (the set of peer names
for this exported service) and iterates over all peering trust bundles, calling
`stringslice.Contains(peerNames, bundle.PeerName)` for each bundle:
```go
// agent/xds/listeners.go
for _, bundle := range cfgSnap.MeshGateway.PeeringTrustBundles { // O(B)
if stringslice.Contains(peerNames, bundle.PeerName) { // O(P) scan
peerBundles = append(peerBundles, bundle)
}
}
```
`stringslice.Contains` is a linear scan:
```go
// lib/stringslice/stringslice.go
func Contains(l []string, s string) bool {
for _, v := range l {
if v == s {
return true
}
}
return false
}
```
The outer caller iterates over all exported services:
```go
for _, svc := range cfgSnap.MeshGatewayValidExportedServices() { // O(S)
peerNames := cfgSnap.MeshGateway.ExportedServicesWithPeers[svc]
filterChain, err := s.makeMeshGatewayPeerFilterChain(cfgSnap, svc, peerNames, chain)
```
Total: O(S × B × P). In a production Consul cluster with S=50 services, B=20 trust
bundles, P=20 peers per service, each listener rebuild costs 50×20×20 = 20,000
string comparisons instead of 50×20 = 1,000 map lookups.
## Fix
Convert `peerNames` to a `map[string]bool` before the bundle loop:
```go
// Before:
var peerBundles []*pbpeering.PeeringTrustBundle
for _, bundle := range cfgSnap.MeshGateway.PeeringTrustBundles {
if stringslice.Contains(peerNames, bundle.PeerName) {
peerBundles = append(peerBundles, bundle)
}
}
// After:
peerNameSet := make(map[string]struct{}, len(peerNames))
for _, p := range peerNames {
peerNameSet[p] = struct{}{}
}
var peerBundles []*pbpeering.PeeringTrustBundle
for _, bundle := range cfgSnap.MeshGateway.PeeringTrustBundles {
if _, ok := peerNameSet[bundle.PeerName]; ok {
peerBundles = append(peerBundles, bundle)
}
}
```
Alternatively, `ExportedServicesWithPeers` could store `map[string]struct{}` instead of
`[]string`, propagating O(1) lookup to all callers.
## Speedup
| S (services) | B (bundles) | P (peers) | Before (ops) | After (ops) | Speedup |
|---|---|---|---|---|---|
| 10 | 10 | 10 | 1,000 | 200 | 5× |
| 50 | 20 | 20 | 20,000 | 2,000 | 10× |
| 100 | 50 | 50 | 250,000 | 10,000 | 25× |