4.9 KiB
Kubernetes — CWE-407 Disclosure Brief
2026-03-27 · Patch available — awaiting upstream merge
Finding
Seven O(n²) defects in Kubernetes's core controllers and scheduler. Defects span the job controller, garbage collector, taint handling, scheduler toleration checks, and pod failure policy evaluation. Measured at 1.67× to 150×. Patches ready for upstream review.
The Defects
kubernetes-0001 (PATCHED — HIGH): pkg/controller/job/job_controller.go
// Inside failure policy eval — per failed pod:
if slices.Contains(values, podValue) { ... } // O(C×R×V) per pod
slices.Contains(Values) O(C×R×V) per failed pod in failure policy evaluation. Measured ratio: 45×.
kubernetes-0002 (PATCHED — HIGH): pkg/controller/garbagecollector/
// Per GC cycle — owner reference lookup:
if slices.Contains(ownerUIDs, uid) { ... } // O(refs×UIDs)
slices.Contains(ownerUIDs) per GC cycle. Fix: map[types.UID]struct{}. Measured ratio: 150×.
kubernetes-0003 (PATCHED — MEDIUM): pkg/controller/job/job_controller.go:1357
// hasJobTrackingFinalizer() called in pass 2 despite uidsWithFinalizer set built in pass 1:
if hasJobTrackingFinalizer(pod) { ... } // Redundant O(P×F) scan
Redundant O(P×F) scan — uidsWithFinalizer.Has(pod.UID) already available. Measured ratio: 1.67×.
kubernetes-0004 (PATCHED — HIGH): pkg/util/taints/taints.go:260
// TaintSetDiff — TaintExists O(T) nested in taint diff loop:
if TaintExists(taints, taint) { ... } // O(T²) in doNoScheduleTaintingPass
O(T²) taint diff in doNoScheduleTaintingPass. Fix: taint key map. Measured ratio: 100×.
kubernetes-0005 (PATCHED — HIGH): pkg/scheduler/.../taint_toleration.go:180
// countIntolerableTaintsPreferNoSchedule — O(T×L) per scheduling cycle:
// for each taint, scan all tolerations
O(T×L) per scheduling cycle. Fix: pre-built toleration set. Measured ratio: 20×.
kubernetes-0006 (PATCHED — LOW): pkg/controller/tainteviction/taint_eviction.go:533
// GetMatchingTolerations O(T×L) per pod per node-taint event
O(T×L) per pod per node-taint event. Fix: toleration map. Measured ratio: 2×.
kubernetes-0007 (PATCHED — MEDIUM): pkg/controller/job/pod_failure_policy.go
// PodFailurePolicy exit-code list — per container-status per pod:
for _, rule := range policy.Rules {
for _, exitCode := range rule.OnExitCodes.Values {
if exitCode == containerExitCode { ... } // O(R×C×V) linear scan
}
}
O(R × C × V) per container-status per pod in failure policy evaluation. Fix: pre-built map[int32]struct{} exit-code set per rule. PATCHED.
Complexity Proof
- kubernetes-0001: O(C×R×V) per failed pod — 45× measured ratio.
- kubernetes-0002: O(refs×UIDs) per GC cycle — 150× measured ratio.
- kubernetes-0004: O(T²) per taint diff — 100× measured ratio.
- kubernetes-0005: O(T×L) per scheduling cycle — 20× measured ratio.
- kubernetes-0007: O(R×C×V) per container-status per pod — pre-built exit-code map fix.
Impact
All Kubernetes clusters. These defects span the job controller (every batch job with failure policies), garbage collector (every resource deletion), taint handling (every node taint change and scheduling cycle), scheduler (every pod scheduling decision), and pod failure policy evaluation (every failed pod with exit-code rules). Kubernetes is the dominant container orchestration platform. Large clusters with many pods, nodes, taints, tolerations, and job failure policies hit all defects under normal operation.
The Fix
All six fixes follow the same pattern — replace slices.Contains / linear scan with a pre-built map or set:
// Before (kubernetes-0002 representative)
if slices.Contains(ownerUIDs, uid) { ... } // O(refs×UIDs)
// After
// CWE-407 fix: map[types.UID]struct{} for O(1) uid check.
if _, ok := ownerUIDSet[uid]; ok { ... }
kubernetes-0007: Pre-build map[int32]struct{} exit-code set per rule:
// Before
for _, exitCode := range rule.OnExitCodes.Values {
if exitCode == containerExitCode { ... } // O(V) scan
}
// After
// CWE-407 fix: pre-built map[int32]struct{} per rule for O(1) exit-code lookup.
exitCodeSet := make(map[int32]struct{}, len(rule.OnExitCodes.Values))
for _, ec := range rule.OnExitCodes.Values { exitCodeSet[ec] = struct{}{} }
if _, ok := exitCodeSet[containerExitCode]; ok { ... }
Patch
defects/kubernetes/patch/kubernetes-0001-through-0007-slices-map.patch
What We Ask
- Confirm receipt and assign a GitHub Security Advisory or issue reference.
- Validate the patch against your controller and scheduler test suites.
- Assess CVE eligibility — kubernetes-0002 measured at 150× in GC hot path.
- Coordinate a disclosure date — we are targeting 90 days from first contact.
Contact: see cover email. This brief is confidential until coordinated disclosure.