Skip to content

feat(node-ensure/delete-untracked/metrics) Ensure there is no extra ARP/FDB configuration when ensuring node endpoints, build OTEL metrics out of control loop#330

Draft
leo-scalingo wants to merge 4 commits into
masterfrom
feat/328/control-loop-ensure-metrics
Draft

feat(node-ensure/delete-untracked/metrics) Ensure there is no extra ARP/FDB configuration when ensuring node endpoints, build OTEL metrics out of control loop#330
leo-scalingo wants to merge 4 commits into
masterfrom
feat/328/control-loop-ensure-metrics

Conversation

@leo-scalingo

Copy link
Copy Markdown
Member

Related to #328

@leo-scalingo leo-scalingo self-assigned this Jul 23, 2026
…RP/FDB configuration when ensuring node endpoints, build OTEL metrics out of control loop

Related to #328
@leo-scalingo
leo-scalingo force-pushed the feat/328/control-loop-ensure-metrics branch from cdfa48c to 82e154b Compare July 23, 2026 10:04
Comment thread node/ensure.go
if err != nil {
// If the netns path no longer exists, deactivate the endpoint. Other
// activation errors should not prevent the remaining endpoints from being ensured.
if os.IsNotExist(errors.Cause(err)) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Semgrep identified an issue in your code:

A wrapped file-not-found error from erepo.Activate(...) may not be recognized here, so missing endpoint.TargetNetnsPath can skip erepo.Deactivate(...). An attacker who can cause stale netns paths during restore could leave orphaned endpoint network state behind.

More details about this

erepo.Activate(...) returns an error, and this code decides whether to clean up the endpoint by checking os.IsNotExist(errors.Cause(err)). That check only looks at the unwrapped cause, so a wrapped not exist error can be missed and the code will take the failed to ensure endpoint path instead of calling erepo.Deactivate(...).

A plausible abuse case is: 1) an attacker causes endpoint.TargetNetnsPath to point to a namespace path that has already been removed, 2) erepo.Activate(endpointCtx, network, endpoint, ...) returns a wrapped file-not-found error for that path, 3) this os.IsNotExist(errors.Cause(err)) check fails to recognize it, and 4) the stale endpoint is left active because erepo.Deactivate(endpointCtx, network, endpoint) is never called. In a system restoring many endpoints, repeatedly triggering this on selected endpoint.NetworkID / endpoint.TargetNetnsPath values can leave orphaned network state behind, which can keep unexpected connectivity or policy state attached to containers that should have been cleaned up.

To resolve this comment:

✨ Commit fix suggestion

Suggested change
if os.IsNotExist(errors.Cause(err)) {
if errors.Is(errors.Cause(err), fs.ErrNotExist) {
View step-by-step instructions
  1. Replace the os.IsNotExist(...) check with the standard library errors.Is(...) check against the not-exist sentinel error.
    Change os.IsNotExist(errors.Cause(err)) to stderrors.Is(err, fs.ErrNotExist).

  2. Stop unwrapping the error with errors.Cause(...) in this condition.
    errors.Is already walks wrapped errors, so it can match the original not-exist error through errors.Wrap, fmt.Errorf(... %w ...), and similar wrappers.

  3. Add the standard library imports needed for the new check.
    If this file already imports github.com/pkg/errors as errors, import the standard library package with an alias such as stderrors "errors", and add io/fs for fs.ErrNotExist.

  4. Keep the existing deactivate path the same, and only update the condition.
    The resulting condition should look like if stderrors.Is(err, fs.ErrNotExist) { ... }.

  5. Alternatively, if this file does not import github.com/pkg/errors with the name errors, use the standard library package directly as errors.Is(err, fs.ErrNotExist).

💬 Ignore this finding

Reply with Semgrep commands to ignore this finding.

  • /fp <comment> for false positive
  • /ar <comment> for acceptable risk
  • /other <comment> for all other reasons

Alternatively, triage in Semgrep AppSec Platform to ignore the finding created by os-error-is-not-exist.

You can view more details about this finding in the Semgrep AppSec Platform.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant