Skip to content

fix(ociruntime): check CAP_SYS_PTRACE on first use, not at package initialization - #512

Draft
achoimet wants to merge 1 commit into
mainfrom
fix/lazy-sys-ptrace-check
Draft

achoimet wants to merge 1 commit into
mainfrom
fix/lazy-sys-ptrace-check

Conversation

@achoimet

Copy link
Copy Markdown
Member

Why

ociruntime decides once, when the package is initialized, whether CAP_SYS_PTRACE is in the effective set (var isCapSysPtraceSet = hasCap(unix.CAP_SYS_PTRACE)). Without it, every namespace lookup falls back to spawning a root readlink process and logs "CAP_SYS_PTRACE capability is not set. Using fallback with reduced performance."

extension-container and extension-host are moving their file capabilities from setcap …+eip to +ip, so that a missing capability no longer makes exec fail (the extension crash-loops today). Their capabilities then only become effective in main() (extruntime.RaiseCapabilities), after package initialization, and this check always sees them missing: every attack would take the slow path, with a false warning.

Seen in the E2E logs of steadybit/extension-container#525: the warning appears 7 times in the PR run vs once on main.

What

Evaluate the check on first use (sync.OnceValue), which happens when an attack runs, after main() has raised the capabilities. Nothing changes for binaries that keep the effective bit.

Related

…itialization

isCapSysPtraceSet was evaluated when the package was initialized, from the
effective capability set. Extensions whose binary carries its file
capabilities without the effective bit (setcap ...+ip) only make them
effective in main(), so the check always failed: every namespace lookup
took the slower fallback (a root readlink process) and logged a false
"CAP_SYS_PTRACE capability is not set" warning.
@claude

claude Bot commented Sep 25, 2026 •

Copy link
Copy Markdown

Claude finished @achoimet's task in 27s —— View job


Claude's Review

  • Gather context (PR body, diff, changed file)
  • Check for previously unresolved Claude review threads (none found — no prior review threads exist on this PR)
  • Review new changes
  • Post final review

Summary

The change moves the CAP_SYS_PTRACE check from package-init time to first-use time via sync.OnceValue, which correctly addresses the described race: extensions using setcap +ip only raise capabilities to effective in main(), after package vars are initialized, so the old eager check always saw the capability as missing.

Correctness / concurrency: sync.OnceValue guarantees hasCap runs exactly once, the result is cached, and concurrent callers are safely synchronized — no race condition introduced. The call site (isCapSysPtraceSet() in executeReadlinkInProc) is updated correctly to invoke the function.

Security: No implications — this only affects the performance fallback path for capability detection logging, not the capability itself.

No bugs, security, or performance issues found. This is a small, well-targeted fix; the added comment clearly explains the non-obvious motivation (why init-time evaluation was wrong).

@sonarqubecloud

Copy link
Copy Markdown

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