CVE-2026-89766
NoneCVSS
—
EPSS
0.2%
Published
Sep 11, 2026
CISA due date
—
Cloudanix analysis
A timing flaw in Linux could let one program peek at another program's private details if the second program switches to a more privileged version at exactly the wrong moment.
- Exploitation
- Local Privilege
- Attacker needs
- Low Privilege
- Complexity
- Moderate
- Impact
- Data Exposure
- Component
- OS kernel
- Class
- Race Condition
- Remediation
- Upgrade
- Effort
- Medium
- Patch risk
- Low
What it actually does
Race condition in pidfd_ioctl() for PIDFD_GET_*_NAMESPACE ioctls that skips exec_update_lock around the ptrace credentials check and namespace lookup, allowing a caller to succeed against stale credentials then obtain a namespace fd after the target execve()s a setuid binary and commits new credentials.
Why it matters to the business
Attackers on multi-user or container hosts could obtain namespace information that should have been denied after a privileged exec, raising the risk of information disclosure or follow-on container escapes and privilege escalation; low EPSS and no KEV status indicate limited observed exploitation so far.
How an attack unfolds
An attacker with a pidfd reference to a target process times a PIDFD_GET_*_NAMESPACE ioctl to pass the ptrace check against the target's old credentials, then reads the namespace fd after the target has execve()d a setuid binary and updated its credentials, bypassing the intended access control that nsfs paths enforce with the lock.
How to fix it
Apply the upstream kernel commit that holds exec_update_lock for reading around the ptrace check and namespace lookup inside pidfd_ioctl(); rebuild and deploy the fixed kernel across all affected hosts.
How to confirm the fix worked
Inspect kernel source for pidfd_ioctl() to confirm exec_update_lock is now acquired before the ptrace_may_access and namespace lookup steps; test with a reproducer that attempts the race after a setuid execve.
Typical attack path
- Obtain a pidfd to the target process
- Trigger or wait for the target to execve() a setuid binary
- Race the namespace ioctl to perform the ptrace check against old credentials
- Receive a namespace file descriptor that would otherwise have been denied
How to detect it
Correlate audit or syscall logs for pidfd ioctl calls (especially namespace variants) occurring in close temporal proximity to execve events of setuid binaries; look for processes obtaining namespace fds after credential changes they should not have been allowed to observe.
What your security team should do
- Prioritize kernel updates on multi-tenant and container hosts where pidfd namespace ioctls are used
- Audit code and workloads that call PIDFD_GET_*_NAMESPACE and restrict the capability where possible
- Enable kernel audit logging for ptrace and execve events to support post-incident review
The record
In the Linux kernel, the following vulnerability has been resolved: pidfd: hold exec_update_lock around namespace ioctl The PIDFD_GET_*_NAMESPACE ioctls in pidfd_ioctl() perform a filesystem credentials ptrace access check before handing out a namespace file descriptor. The accompanying comment states that the code "mirrors nsfs behavior", but, unlike the corresponding procfs paths, it does so without holding the target task's exec_update_lock. proc_ns_get_link() and proc_ns_readlink() both take exec_update_lock for reading around the ptrace check and the namespace lookup, so that the credentials used for the access decision match those of the task when its namespace is read. Without it, a caller can pass the check against the target's old credentials and then read the namespace after the target has execve()'d a setuid binary and committed new credentials -- accessing namespace information it should have been denied. Hold exec_update_lock for reading around the ptrace check and the namespace lookup so that pidfd truly mirrors nsfs behavior, as the comment already claims. open_namespace() itself runs outside the lock: once a namespace reference is obtained it carries its own refcount and is opened with the caller's own credentials, so a concurrent execve() on the target can no longer affect the outcome.
Affected packages
| Ecosystem | Package | Introduced | Fixed |
|---|