On May 14, Qualys’ Threat Research Unit dropped CVE-2026-46333 — nicknamed ssh-keysign-pwn — and a working proof-of-concept landed on GitHub the same day. The bug is a ptrace access-control race that has been sitting in the mainline Linux kernel since v4.10-rc1 in 2017 (commit bfedb589), and it gives any unprivileged local user a clean read primitive over root-owned files. The two SUID binaries that matter in the public exploit are ssh-keysign (it opens /etc/ssh/ssh_host_*_key) and chage (it opens /etc/shadow). Steal either set and you skip straight to host impersonation or offline hash cracking.
Linus committed the fix (31e62c2ebbfd) the same day the disclosure went public, and patched stable trees rolled the next morning: 7.0.8, 6.18.31, 6.12.89, 6.6.139, 6.1.173, 5.15.207, and 5.10.256. If you’re behind any of those tags on a multi-user box, fix it tonight.
The bug
The vulnerable path lives in __ptrace_may_access(). When a thread is exiting, the kernel detaches its mm_struct (memory descriptor) before it tears down the file descriptor table. There is a window — narrow but reliably hittable — during which task->mm == NULL but task->files is still populated with open root-owned descriptors.
__ptrace_may_access() short-circuits on task->mm == NULL and skips the dumpability check entirely. That check is what normally prevents an unprivileged caller from reaching into a privileged process. With the check elided, an attacker process whose UID matches the dying process can call pidfd_getfd(2) — the file-descriptor cloning syscall introduced in 5.6 — and copy descriptors out of the exiting privileged process before its files_struct is freed.
Jann Horn flagged this exact class of issue in a 2020 patch proposal that never got merged. The race has been latent for six years.
The PoC’s loop is mechanical: spawn ssh-keysign (or chage) in a tight fork/exec loop, watch /proc/<pid>/status for the moment mm goes away, fire pidfd_getfd against each fd in /proc/<pid>/fd/, then read() whatever you scraped. On a quiet machine the race fires inside a few hundred iterations.
Who’s affected
Per Qualys and downstream advisories, the public PoC works out of the box on:
- Debian 11, 12, 13
- Ubuntu 22.04, 24.04, 26.04
- Arch Linux (current)
- Raspberry Pi OS Bookworm
- RHEL / AlmaLinux / Rocky 9 and 10 (EL9, EL10)
- CloudLinux 8 LTS, 9, and 10
CloudLinux 7 (kernel 3.10) and other distros still on pre-4.10 kernels are not affected — the race was introduced after their fork point. If you’re running a long-tail enterprise kernel, confirm the backport status before assuming you’re clear; the EL families have shipped 4.x and 5.x with this code path.
What makes this nastier than the usual local-info-leak is the kind of file it leaks. SSH host private keys let an attacker impersonate the box on its network — your bastion is now somebody else’s MITM endpoint, and downstream clients with StrictHostKeyChecking=yes will trust the forgery. /etc/shadow hands over every local password hash for offline cracking. Either outcome is a full pivot for any tenant on a shared host: container build farms, CI runners, multi-user developer boxes, shared bastions, university clusters, web hosting control panels.
Fix or mitigate, today
The proper fix is the patched kernel. Roll one of these and reboot:
- 7.0.8, 6.18.31, 6.12.89, 6.6.139, 6.1.173, 5.15.207, 5.10.256
- Debian, Ubuntu, AlmaLinux, Rocky, RHEL, Arch, and the CloudLinux family have all shipped advisories within 24 hours of disclosure —
apt/dnf/pacmanupgrade and reboot.
If you can’t reboot inside the maintenance window, the single-line mitigation is Yama’s ptrace_scope:
| |
Level 2 (admin-only attach) blocks every public exploit; level 3 (no attach at all) is even safer if your workload tolerates it. Note this breaks gdb and any tool that relies on ptrace for non-children, so test before rolling fleet-wide. Some debugger-heavy environments — game dev shops, crash-dump tooling, language runtimes that use ptrace for instrumentation — will notice. Most production hosts won’t.
As a defense in depth, audit which SUID binaries with privileged file handles live on your systems beyond ssh-keysign and chage. The exploit primitive is generic; the public PoC happens to target the two most damaging ones, but anything that opens a privileged file while exit-racing is in scope.
Why this one matters
This is Qualys’ fourth Linux kernel disclosure in three weeks, and the second this year that punches through dumpable/ptrace boundaries. Patch latency on local LPEs tends to be longer than RCEs because nobody wants to reboot — but ssh-keysign-pwn is the rare LPE where the file you exfiltrate is the lateral movement. There is no second stage to engineer. Read the file, ssh-impersonate the host, crack the hash, move on.
If you run any environment where local user accounts you don’t fully trust share a kernel with privileged files you care about, treat this as a same-night fix.
References
- Qualys disclosure coverage (Phoronix, 9to5Linux, CyberSecurityNews)
- Linus’ fix: kernel commit
31e62c2ebbfd - PoC:
github.com/0xdeadbeefnetwork/ssh-keysign-pwn - Red Hat advisory:
access.redhat.com/security/cve/cve-2026-46333 - AlmaLinux patches advisory (2026-05-15)
- CloudLinux mitigation guide