2.4 KiB
UNDF: UNDF-2026-000000427
istio-0001: CWE-407 — Linear gateway membership scan inside VirtualService reconciliation loop
Severity: HIGH
Repository
github.com/istio/istio Commit: d9ada8a
File
pilot/pkg/model/push_context.go
Defective Lines
1764: for _, virtualService := range vservices { // outer: O(V) virtual services
...
1839: if features.EnableAmbientWaypoints && (len(rule.Gateways) == 0 ||
1839: slices.Contains(rule.Gateways, constants.IstioMeshGateway)) {
Complexity
O(V × G) where V = number of VirtualServices, G = number of gateways per VS rule. Called during every push-context rebuild (config change, endpoint change, xDS push).
Root Cause
slices.Contains performs a linear scan over rule.Gateways []string for each
VirtualService in the full mesh inventory. In large installations with hundreds of
VirtualServices each listing multiple gateways, this compounds with the outer loop.
The check slices.Contains(rule.Gateways, constants.IstioMeshGateway) asks: "is
the literal string mesh in this slice?" This is a set-membership test performed
with a sequential scan every reconciliation cycle.
Impact
Pilot push latency increases quadratically with the number of VirtualServices ×
average gateway list length. Push-context rebuilds block xDS delivery to all
sidecars and gateways during the rebuild window. Measured degradation appears as
elevated pilot_xds_push_time and pilot_push_context_errors in production
clusters with 500+ VirtualServices using Ambient Waypoints.
Fix
Pre-index rule.Gateways as a map[string]struct{} (or sets.String) before the
VirtualService loop. The constant constants.IstioMeshGateway lookup becomes O(1).
// Before (defective):
if features.EnableAmbientWaypoints && (len(rule.Gateways) == 0 ||
slices.Contains(rule.Gateways, constants.IstioMeshGateway)) {
// After (fixed): build a set once per VS, or check via a pre-built map
gwSet := sets.NewSet(rule.Gateways...)
if features.EnableAmbientWaypoints && (gwSet.Len() == 0 ||
gwSet.Contains(constants.IstioMeshGateway)) {
For the common case where rule.Gateways has 1–3 entries the allocation cost of a
map outweighs the scan; a sorted slice + binary search (O(log G)) eliminates the
asymptotic defect without allocation overhead.
References
- CWE-407: Inefficient Algorithmic Complexity
pilot/pkg/model/push_context.goinitVirtualServices() ~line 1764