java-topology/whitepaper/outreach/containerd.md

2.6 KiB

containerd — CWE-407 Disclosure Brief

2026-03-27 · Patch available — awaiting upstream merge

Finding

One O(n²) defect in containerd's OCI spec options. filterCaps and WithAddedCapabilities use slices.Contains (via capsContain()) causing O(n²) capability set processing per container launch. Patch ready for upstream review.

The Defects

containerd-0001 (PATCHED — HIGH): pkg/oci/spec_opts.go:1069,1080

// filterCaps / WithAddedCapabilities — per container launch:
func capsContain(caps []string, s string) bool {
    return slices.Contains(caps, s)  // O(n) per cap check
}
// Called inside loop over all capabilities:
for _, cap := range allCaps {
    if !capsContain(filteredCaps, cap) {  // O(n²) total
        ...
    }
}

capsContain() wraps slices.Contains and is called inside a loop over all capabilities. For N capabilities: O(N²) per container launch. Fix: map[string]bool capability set.

Complexity Proof

For N capabilities (Linux has ~40 capabilities):

  • Per container launch: O(N²) comparisons
  • Fixed: map[string]bool cap set → O(N)
  • At N=40: 1,600 comparisons vs 40 map lookups
  • Scales with custom capability sets; notable for high container launch rate environments.

Impact

All containerd deployments launching containers with capability filtering — virtually all production Kubernetes deployments (containerd is the default CRI). Container launches with WithAddedCapabilities, WithDroppedCapabilities, and WithCapabilities spec options all hit this path. Kubernetes nodes with high pod churn (auto-scalers, batch workloads, CI/CD systems) launch many containers per minute.

The Fix

Replace capsContain() with a map[string]bool capability set:

// Before
func capsContain(caps []string, s string) bool {
    return slices.Contains(caps, s)  // O(n)
}

// After
// CWE-407 fix: map[string]bool for O(1) cap check instead of O(n) slices.Contains.
func buildCapSet(caps []string) map[string]bool {
    set := make(map[string]bool, len(caps))
    for _, c := range caps { set[c] = true }
    return set
}
// Use: capSet[cap] instead of capsContain(caps, cap)

Patch

defects/containerd/patch/containerd-0001-spec-opts-cap-map.patch

What We Ask

  1. Confirm receipt and assign a GitHub Security Advisory or issue reference.
  2. Validate the patch against your OCI spec and capability test suite.
  3. Assess CVE eligibility — fires on every container launch with capability filtering.
  4. Coordinate a disclosure date — we are targeting 90 days from first contact.

Contact: see cover email. This brief is confidential until coordinated disclosure.