java-topology/defects/istio/patch/istio-0002-push-context-gateway-linear-scan.md

2.4 KiB
Raw Blame History

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 13 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.go initVirtualServices() ~line 1764