Skip to main content

merge_context_pair

Function merge_context_pair 

Source
pub fn merge_context_pair(
    base_sc: Option<&SecurityContext>,
    base_psc: Option<&PodSecurityContext>,
    over_sc: Option<&SecurityContext>,
    over_psc: Option<&PodSecurityContext>,
) -> (Option<SecurityContext>, Option<PodSecurityContext>)
Expand description

THE layer merge: overlay one (container, pod) security-context layer pair onto another. Every layer fold — resolve_mover’s hardened ⊂ moverDefaults ⊂ recipe and the controller’s inherited ⊂ explicit pre-fold — MUST go through this function; a lone per-dimension merge_security_context/merge_pod_security_context reintroduces cross-dimension identity shadowing.

Two steps:

  1. Field-wise merge per dimension (the exhaustive-literal primitives above).
  2. Identity promotion to canonical form: the kubelet resolves the effective UID/GID as container ?? pod ACROSS the two dimensions, so a lower layer’s container-level runAsUser would silently shadow a higher layer’s pod-level one — inverting the layer ladder (the matter-server bug). The merged pair therefore keeps its container context, when one exists, carrying the pair’s effective UID/GID: the over layer’s pinned identity wins, else the base’s (hoisted from the pod level when that’s where the winning layer wrote it). When no layer supplied a container context there is nothing to shadow, and the field-wise pod result already carries the over layer’s identity.

The canonical form is what makes the merge associative (so the controller’s pre-fold + resolve_mover’s fold equals a flat four-layer merge): with E(L) = layer L’s own effective UID, the merged container runAsUser is exactly E(over).or(E(base)), so any grouping of hardened ⊂ moverDefaults ⊂ inherited ⊂ explicit resolves the identity of the highest layer that pins one. (A promotion keyed only on over’s own identity is NOT associative: once over is itself a merged pair, its pod-level identity — contributed by a lower layer — would be re-promoted in one grouping and not the other.) Identically for the GID. Within a single layer, container still beats pod — exactly the kubelet’s own rule.