fix(presets): use continue instead of return for stale CID in preset …#2770
Open
VirajMandavkar wants to merge 1 commit into
Open
fix(presets): use continue instead of return for stale CID in preset …#2770VirajMandavkar wants to merge 1 commit into
VirajMandavkar wants to merge 1 commit into
Conversation
…loop Preset enforcer's UpdateSecurityPolicies exits the entire function via `return` when a container CID isn't yet registered in ContainerMap, instead of skipping just that container. Since this check runs inside the container iteration loop, any container appearing after a stale CID is silently left without preset rule enforcement. The stale-CID guard itself is valid (CRI may unregister a container before K8s sends the update), but the exit behavior was too broad. Changed `return` to `continue` so remaining containers are still processed. Signed-off-by: VirajMandavkar <mandavkarviraj03@gmail.com>
VirajMandavkar
requested review from
Aryan-sharma11,
AryanBakliwal and
achrefbensaad
as code owners
July 13, 2026 19:24
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Purpose of PR?:
While digging into #2761 I found another bug in the preset enforcer's container loop (
KubeArmor/presets/protectproc/preset.go, around line 288), insideUpdateSecurityPolicies.There's already a check here for a legit race condition — CRI can unregister a container before K8s sends the update through, so the code checks if the CID is even in
ContainerMapbefore applying rules:
That check is fine, the problem is what happens after it fails.
returnhere doesn't just skip the current container - it exits the whole function. Since this is inside a loop overendPoint.Containers, if even one CID in the middle of the list isn't registered yet, every container that comes after it in that iteration gets skipped entirely. No preset rules applied, no error surfaced anywhere, KubeArmor just carries on like everything's protected.Fixes # (haven't filed a separate issue for this one, flagging directly — found while working on #2761)
Does this PR introduce a breaking change?
No
If the changes in this PR are manually verified, list down the scenarios covered:
returnis inside the loop — so this isn't something that only shows up under specific timing, it's just how the loop is written. Any miss anywhere in the list kills processing for the rest.Additional information for reviewer?:
Root cause
The race condition check itself was clearly intentional and it's a real scenario worth guarding against. But bailing out of the entire function because one container in the list isn't ready yet doesn't make sense — the other containers in the pod are unrelated and shouldn't be affected. Swapping
returnforcontinuekeeps the original intent (skip this one container) without taking down enforcement for everyone else in the same call.The fix
On proof/evidence — being upfront here since I couldn't fully nail this down live: I was able to consistently trigger the warning log by killing containers and forcing stale CIDs, so I know this branch does get hit in real clusters. What I couldn't do is capture a clean log showing one specific later container getting skipped because of it — timestamps were too close together (sub-millisecond) to say for certain in a live run. That said, I don't think that ambiguity matters much here, because this isn't really a "maybe it happens" bug.
returninside a Go for-loop will always skip everything after it once hit — that's just what the keyword does, it's not conditional on timing or environment. Happy to add a unit test that isolates the loop logic directly (fake ContainerMap missing a middle CID, assert the containers after it still get processed) if that's useful for review — can push that as a follow-up commit.How to reproduce
crictl stopworks fine).container not registered in mapfire for that CID.endPoint.Containers— right now they won't get preset rules applied for that call.return→continue, repeat the steps — the rest of the containers should get processed regardless of the earlier miss.Checklist:
<type>(<scope>): <subject>