This is a loose deadbolt on the server-room door that only matters once someone is already in the hallway
CVE-2026-46333 is a Linux kernel ptrace authorization bug in __ptrace_may_access() / get_dumpable() that mishandles tasks whose mm is already gone during process teardown. In practice, a low-privileged local user can race a privileged process as it exits, then use pidfd_getfd() or related ptrace-gated paths to steal open file descriptors or authenticated IPC handles. Upstream exposure reaches back to mainline v4.10-rc1 in November 2016; upstream fix landed by 7.1-rc4, with stable and distro backports shipping separately.
Vendor HIGH is directionally fair, but the *real* story is narrower than the raw impact suggests: this is not unauthenticated remote RCE, it is a post-initial-access kernel LPE / sensitive-file theft path. The downgrade pressure is the required local foothold; the upgrade pressure is that public PoCs worked against default installs on major distros and can convert a mundane shell on a shared host, CI runner, desktop, or container node into host-level compromise.
4 steps from start to impact.
Land a local low-priv shell
- Unprivileged code execution on the target Linux host
- Kernel branch that predates the relevant backport/fix
- Requires post-initial-access position
- Single-user appliances and tightly locked-down servers reduce reachable population
- Ephemeral containers with strong isolation may limit useful post-exploit impact
Trigger a vulnerable privileged helper
ssh-keysign-pwn or ptrace_may_dream, the attacker launches or waits for a privileged process that opens sensitive files or holds a privileged IPC channel while exiting. Qualys demonstrated practical targets including chage, ssh-keysign, pkexec, and accounts-daemon on default distro installs.- A usable SUID/SGID/helper or root daemon path exists on that build
- The target process opens something worth stealing before exit
- Not every host has the same helper binaries installed or reachable
- Some paths depend on desktop/polkit/dbus presence rather than headless-server defaults
ssh-keysign, chage, pkexec, or repeated short-lived helper invocations, but most vuln scanners won't test exploitability at this layer.Race teardown and duplicate descriptors
mm is gone but its files or authenticated channels are not yet fully torn down. The weaponized syscall path is typically pidfd_getfd(), which leans on the flawed ptrace access decision; the attacker duplicates a target descriptor into their own process before it disappears.- Known exploit path using
pidfd_getfd()or equivalent ptrace-gated access - Default or permissive enough ptrace policy, commonly
kernel.yama.ptrace_scope=1
- Racy exploitation is harder than a straight logic bug, though public PoCs lowered that barrier
- Raising
kernel.yama.ptrace_scopeto2blocks the public exploit path - Seccomp profiles that deny
pidfd_getfdreduce containerized abuse
pidfd_getfd, ptrace, process_vm_readv, and /proc/<pid> access spikes. Most EDRs do not have high-fidelity signatures for this exact kernel race.Turn stolen access into root impact
/etc/shadow, steal SSH host keys, or reuse authenticated D-Bus/system service channels to execute commands as root. At that point the host is effectively compromised, and the kernel bug has served as the privilege-boundary bypass.- Stolen descriptor or IPC handle maps to sensitive material or privileged actions
- Attacker can operationalize the captured handle before it is invalidated
- Impact varies by workload; a generic desktop/lab host may expose less than a shared infra node
- Key theft may still require follow-on action to monetize, such as cracking or operational reuse
dbus-send/systemd abuse, and anomalous child processes under privileged services.The supporting signals.
| In-the-wild status | No KEV listing as of today, and I found no primary-source evidence of active exploitation campaigns. What *is* confirmed is fast public weaponization after disclosure via the public kernel fix and GitHub PoCs. |
|---|---|
| Public exploit status | High. Qualys reported four working exploits internally, and public repos referenced by Debian/NVD include 0xdeadbeefnetwork/ssh-keysign-pwn and sgkdev/ptrace_may_dream. |
| EPSS | User-supplied EPSS is 0.00007 (*~0.007%*), which is very low and consistent with a post-compromise local bug rather than mass remote exploitation. |
| KEV status | Not listed in the CISA KEV catalog at the time of this assessment. |
| CVSS context | CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N means local, low-complexity, low-privilege exploitation with high confidentiality and integrity impact. The important translation: *already on box* is the decisive gate. |
| Affected range | Upstream exposure dates back to mainline v4.10-rc1 (November 2016) per Qualys. In practice, affectedness is kernel-package specific because enterprise distros backport fixes rather than tracking pure upstream version numbers. |
| Fixed versions | Upstream mainline fix is present by 7.1-rc4; Debian tracker shows fixes such as Bullseye 5.10.257-1, Bookworm 6.1.174-1, and Trixie 6.12.90-2. Red Hat, Ubuntu, and others are shipping backported kernels, so distro advisory status beats uname -r alone. |
| Exposure / scanning reality | There is no meaningful Shodan/Censys/GreyNoise fingerprint here because the bug is local-only. Prioritize hosts where untrusted or semi-trusted users get shells: bastions, VDI, CI runners, Kubernetes nodes, shared research boxes, jump hosts, and desktop fleets. |
| Disclosure timeline | CVE published 2026-05-15; Qualys says it privately reported the flaw on 2026-05-11, upstream patch landed on 2026-05-14, and full public advisory followed on 2026-05-20/22 after independent exploit material appeared. |
| Researcher / reporting org | Discovered and published by Qualys Threat Research Unit (TRU); the Linux CNA is kernel.org. |
noisgate verdict.
The single most decisive factor is that this bug requires a local foothold, which makes it a post-compromise privilege-escalation issue rather than an initial-access crisis. It still lands in HIGH because public PoCs worked against default installs on major distros and the blast radius, once triggered, is full host compromise or credential/key theft.
Why this verdict
- Downward pressure: local foothold required —
AV:L/PR:Lmeans the attacker is already executing on the host. That implies an earlier compromise stage or insider access, so this is *not* a fleet-wide internet emergency in the same class as pre-auth RCE. - Upward pressure: exploit paths are public and practical — Qualys demonstrated default-install abuse through
chage,ssh-keysign,pkexec, andaccounts-daemon, and public repos appeared quickly. This is not a purely theoretical kernel edge case anymore. - Downward pressure: reachable population is narrower than 'all Linux' — exploitation depends on the host having useful privileged helpers/daemons and on local users actually being able to run code there. Your locked-down appliances and single-purpose servers are less exposed than shared compute and developer estates.
- Upward pressure: kernel-level boundary bypass means big blast radius per host — once the local attacker wins, they can steal SSH host keys, disclose
/etc/shadow, or pivot to root actions. On a Kubernetes node, CI runner, jump host, or VDI system, that's enough to turn one shell into platform-level trouble. - Downward pressure: modern controls can cut the chain —
kernel.yama.ptrace_scope=2, seccomp that blockspidfd_getfd, and tight local-user policy all materially reduce exploitability. The public exploit chain is not unstoppable in hardened deployments.
Why not higher?
This is not unauthenticated remote, not wormable, and not broadly externally discoverable. The attack assumes a prior compromise stage and then depends on host role, available privileged helpers, and ptrace policy; those are real friction points that keep it out of CRITICAL.
Why not lower?
A MEDIUM rating would undersell the fact that public PoCs turn ordinary low-privileged execution into root or key theft on common default builds. Kernel LPEs on shared Linux infrastructure routinely become business-impacting fast because the step from 'shell on host' to 'full host compromise' is operationally short.
What to do — in priority order.
- Raise
kernel.yama.ptrace_scopeto2— Deploy within 30 days to meet the HIGH noisgate mitigation SLA. This blocks the publicly documentedpidfd_getfd()/ ptrace-gated exploit path for unprivileged users on most production Linux hosts; validate impact ongdb -p,strace -p, CRIU, and similar debugging workflows before broad rollout. - Block
pidfd_getfdin container seccomp profiles — Deploy within 30 days on Kubernetes and container estates where workload debugging does not require it. This is especially valuable on shared nodes because it removes the syscall most public exploit chains rely on, shrinking the practical attack surface even before patching. - Prioritize shared-shell and multi-tenant Linux systems — Within 30 days, identify bastions, CI runners, VDI, lab boxes, university-style multi-user servers, and Kubernetes nodes that grant user-level code execution. Those are the systems where the local-footprint prerequisite is common enough that this CVE behaves like a real escalation path instead of a paper risk.
- Review and restrict local execution paths — Within 30 days, tighten who gets SSH, shell,
kubectl exec, debug containers,oc debug, and privileged job execution. This does not fix the bug, but it directly attacks the biggest prerequisite in the chain: getting a low-privileged local process onto the host.
WAF,NGFW, and perimeter IDS do nothing meaningful here because the exploit is local-only and rides kernel syscalls after the attacker is already on the host.- MFA is good for preventing the *first* compromise, but it does not stop post-login local kernel exploitation once an attacker already has code execution.
- Assuming
SELinux enforcingalone solves it is overconfident. It may reduce some post-exploit actions, but Red Hat explicitly treats patching as the only comprehensive remediation. - Version checks based only on
uname -rare unreliable on enterprise distros because of backported kernel fixes.
Crowdsourced verification payload.
Run this on the target Linux host as a normal user; sudo is only needed if your package manager restricts changelog access. Invoke it as bash check-cve-2026-46333.sh or bash check-cve-2026-46333.sh --verbose. It checks for distro-package changelog evidence first, then falls back to cautious upstream-version logic; if backports make the answer ambiguous, it returns UNKNOWN rather than guessing.
#!/usr/bin/env bash
# check-cve-2026-46333.sh
# Exit codes:
# 0 = PATCHED
# 1 = VULNERABLE
# 2 = UNKNOWN / could not determine reliably
set -u
VERBOSE=0
[[ "${1:-}" == "--verbose" ]] && VERBOSE=1
log() {
[[ "$VERBOSE" -eq 1 ]] && echo "[info] $*" >&2
}
result_unknown() {
echo "UNKNOWN"
exit 2
}
result_vuln() {
echo "VULNERABLE"
exit 1
}
result_patched() {
echo "PATCHED"
exit 0
}
kernel_rel="$(uname -r 2>/dev/null || true)"
[[ -z "$kernel_rel" ]] && result_unknown
ptrace_scope="unknown"
if [[ -r /proc/sys/kernel/yama/ptrace_scope ]]; then
ptrace_scope="$(cat /proc/sys/kernel/yama/ptrace_scope 2>/dev/null || echo unknown)"
fi
log "kernel=$kernel_rel ptrace_scope=$ptrace_scope"
# -------- helpers --------
ver_ge() {
# returns 0 if $1 >= $2 using sort -V
[[ "$(printf '%s\n%s\n' "$1" "$2" | sort -V | tail -n1)" == "$1" ]]
}
extract_upstream_base() {
# Strip common distro suffixes after first '-'
printf '%s' "$1" | sed 's/-.*$//'
}
check_dpkg_changelog() {
command -v dpkg-query >/dev/null 2>&1 || return 1
local pkg
pkg="$(dpkg-query -S "/boot/vmlinuz-$kernel_rel" 2>/dev/null | head -n1 | cut -d: -f1)"
[[ -z "$pkg" ]] && return 1
log "dpkg package=$pkg"
local hit=1
if command -v zgrep >/dev/null 2>&1; then
zgrep -Eiq 'CVE-2026-46333|slightly saner .get_dumpable.|__ptrace_may_access' /usr/share/doc/"$pkg"/changelog* 2>/dev/null && hit=0
else
grep -Eiq 'CVE-2026-46333|slightly saner .get_dumpable.|__ptrace_may_access' /usr/share/doc/"$pkg"/changelog* 2>/dev/null && hit=0
fi
return "$hit"
}
check_rpm_changelog() {
command -v rpm >/dev/null 2>&1 || return 1
local pkg
pkg="$(rpm -q --whatprovides "kernel-uname-r = $kernel_rel" 2>/dev/null | head -n1)"
[[ -z "$pkg" ]] && return 1
log "rpm package=$pkg"
rpm -q --changelog "$pkg" 2>/dev/null | grep -Eiq 'CVE-2026-46333|slightly saner .get_dumpable.|__ptrace_may_access'
}
# -------- strongest signal: local package changelog --------
if check_dpkg_changelog; then
log "found changelog evidence of fix in dpkg package"
result_patched
fi
if check_rpm_changelog; then
log "found changelog evidence of fix in rpm package"
result_patched
fi
# -------- fallback: cautious upstream-version check --------
base_ver="$(extract_upstream_base "$kernel_rel")"
log "upstream-like base version=$base_ver"
# Distro/backport kernels are ambiguous if no package changelog evidence was found.
# Return UNKNOWN rather than guessing from uname -r alone.
if [[ "$kernel_rel" =~ (ubuntu|el[0-9]|amzn|aws|azure|gcp|generic|deb|fc[0-9]|arch|suse) ]]; then
log "vendor/backport kernel string detected; uname -r alone is not authoritative"
result_unknown
fi
# Known upstream thresholds from public advisories:
# 5.10.x fixed by 5.10.257
# 6.1.x fixed by 6.1.174
# 6.12.x fixed by 6.12.90
# 7.0.x fixed by 7.0.10
# 7.1-rc4 and later fixed in mainline
case "$base_ver" in
5.10.*)
if ver_ge "$base_ver" "5.10.257"; then result_patched; else result_vuln; fi
;;
6.1.*)
if ver_ge "$base_ver" "6.1.174"; then result_patched; else result_vuln; fi
;;
6.12.*)
if ver_ge "$base_ver" "6.12.90"; then result_patched; else result_vuln; fi
;;
7.0.*)
if ver_ge "$base_ver" "7.0.10"; then result_patched; else result_vuln; fi
;;
7.1-rc*|7.1)
# Treat 7.1-rc4+ as patched; plain 7.1 final is patched.
if [[ "$base_ver" == "7.1" ]]; then
result_patched
fi
rcnum="$(printf '%s' "$base_ver" | sed -n 's/^7\.1-rc\([0-9]\+\)$/\1/p')"
[[ -n "$rcnum" ]] || result_unknown
if [[ "$rcnum" -ge 4 ]]; then result_patched; else result_vuln; fi
;;
*)
# Branches like 6.6.x / 6.15.x may be fixed by backport, but we don't guess.
result_unknown
;;
esac
If you remember one thing.
ptrace_scope=2 control there first to meet the noisgate mitigation SLA of within 30 days; then drive vendor kernel updates through normal maintenance to meet the noisgate remediation SLA of within 180 days. If a host has hosted untrusted users and you confirm exploit attempts or cannot rule them out, add SSH host key review/rotation and credential hygiene to the response, because the likely impact is theft of root-owned files or root-equivalent action on that host.Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.