CIFSwitch: Local Privilege Escalation in cifs-utils (Root via SMB Helper)
A 19-Year-Old Kernel Bug, Found by Machine Learning, Gives Root
Asim Manizada found and disclosed a privilege escalation in the Linux kernel's CIFS (SMB file sharing) subsystem called CIFSwitch. The vulnerability chains four normal pieces of Linux infrastructure—keyrings, the cifs.upcall helper, user namespaces, and the Name Service Switch—to give any unprivileged local user a reliable path to root.
The kernel code path dates back to 2007. It stayed dormant for 19 years because the practical exploit chain depends on two later additions: unprivileged user namespaces (Linux 3.8, 2013) and the namespace-switching logic in cifs-utils (6.14+). Without all three pieces present, the chain doesn't work end-to-end.
Severity: High for most Linux distributions. Immediate mitigation is straightforward.
Who's Vulnerable
Out-of-the-box vulnerable (cifs-utils preinstalled, unprivileged namespaces enabled, default LSM policy permits the chain):
- AlmaLinux 9.7 (Workstation and Azure image)
- Rocky Linux 9 Workstation
- CentOS Stream 9 GNOME
- Linux Mint 21 and 22
- Kali Linux 2021.4 through 2026.1 (headless)
- SLES 15 SP7 and SP8
- SLES SAP 15 SP7 and 16
- CloudLinux 10
Vulnerable if cifs-utils is manually installed:
- Ubuntu 18.04, 20.04, 22.04, 24.04 (Desktop and Server)
- Debian 11, 12, 13
- openSUSE Leap 15.6
- Oracle Linux 8, 9
- Amazon Linux 2023
Blocked by default policy (but vulnerable if LSM is disabled):
- RHEL 10, AlmaLinux 10, Rocky 10, Oracle 10 (SELinux blocks by default)
- Ubuntu 26.04 (AppArmor blocks by default)
- Fedora 40+, CentOS Stream 10 (blocked by default)
Not vulnerable:
- Amazon Linux 2 (ships older cifs-utils 6.2 without namespace logic)
- CentOS 7, RHEL 7 (unprivileged namespaces disabled by default)
- Kali 2019.4, 2020.4 (older cifs-utils 6.9)
How the Exploit Works: The Trust Boundary That Doesn't Exist
The chain is elegant in its simplicity. Each piece does what it's designed to do. The bug is that one trust boundary between kernel and userspace was never enforced.
Step 1: The Kernel Keyrings Subsystem
Linux keyrings stores authentication material (Kerberos tickets, encryption keys, credentials). When the kernel needs a key it doesn't have, it calls out to userspace to produce one. A rule in /etc/request-key.d/ says: "to produce a key of type cifs.spnego, run /usr/sbin/cifs.upcall as root."
The kernel builds a description string carrying authority-bearing fields: user ID, credential UID, process ID, target namespace. That description is supposed to come only from the kernel. Userspace helpers trust those fields.
Step 2: The Missing Kernel Validation (The Bug)
Before the patch, the kernel's cifs_spnego_key_type was missing the .vet_description hook. Without it, any unprivileged process can call request_key() directly and ask for a cifs.spnego key with a forged description. The kernel has no check to say "only trust descriptions from my CIFS code path."
Critical detail: The kernel doesn't even need to return a valid key. The helper launches first. By the time the kernel rejects the key, cifs.upcall is already running as root with the attacker's forged description in hand.
Step 3: Namespace Switching Inside the Root Helper
cifs.upcall parses the description, finds upcall_target=app and pid=<attacker-pid>, and calls setns() to switch into the attacker's namespace. This is a legitimate feature—it lets cifs.upcall resolve mount names against the right filesystem and network view for containerized mounts.
The problem: The kernel just tricked cifs.upcall into trusting an attacker's PID as if it came from a real kernel-side CIFS operation.
Step 4: Code Loading via NSS
Before dropping privileges, cifs.upcall calls getpwuid() to do an account lookup. On Linux, account lookups go through the Name Service Switch (NSS), a pluggable system configured in /etc/nsswitch.conf that loads shared libraries (libnss_*.so.2) for each lookup type.
Now that cifs.upcall is inside the attacker's namespace, it reads the attacker's /etc/nsswitch.conf and loads the attacker's NSS module. That shared object runs as root.
Step 5: Persistence via Sudo
The public PoC's NSS module writes a file under /etc/sudoers.d/ granting NOPASSWD: ALL access. After the helper exits, the attacker runs sudo and gets a root shell.
The fix: The upstream patch adds a four-line cifs_spnego_key_vet_description() function that compares the current credentials against the kernel's private spnego credentials. If they don't match, the request is rejected with -EPERM. Only the kernel's own CIFS code path is allowed to instantiate this key type.
Immediate Mitigation: Two Clean Options
Option 1: Override the default cifs.spnego request-key rule (if you don't mount Kerberos SMB shares)
Most servers don't use Kerberos-authenticated SMB mounts. If yours doesn't, override the default rule:
echo 'create cifs.spnego * * /usr/sbin/keyctl negate %k 30 %S' | sudo tee /etc/request-key.d/cifs.spnego.conf
This stops the chain at step 1 by negating key requests instead of calling the vulnerable helper.
⚠️ Only if you don't mount Kerberos SMB shares. If you do, cifs.upcall is exactly what you need for authentication.
Option 2: Disable unprivileged user namespaces (if you don't run rootless containers)
The PoC must enter a private user and mount namespace to trigger the upcall. Blocking unprivileged namespaces kills the chain regardless of cifs-utils state.
Red Hat family (EL8, EL9, CloudLinux, etc.):
sudo sysctl -w user.max_user_namespaces=0
echo 'user.max_user_namespaces = 0' | sudo tee /etc/sysctl.d/99-cifswitch.conf
Debian/Ubuntu:
sudo sysctl -w kernel.unprivileged_userns_clone=0
echo 'kernel.unprivileged_userns_clone = 0' | sudo tee /etc/sysctl.d/99-cifswitch.conf
⚠️ Trade-off: Rootless container runtimes (rootless Podman, rootless Docker), Flatpak sandboxing, and some CI systems require unprivileged namespaces. This mitigation breaks those.
Option 3: Uninstall cifs-utils (if you don't use SMB client mounts)
Most server fleets don't need it:
# Debian/Ubuntu
sudo apt remove cifs-utils
# RHEL/AlmaLinux/Rocky/Oracle/CentOS
sudo dnf remove cifs-utils
Check If You're Vulnerable Right Now
# Is cifs-utils installed?
command -v cifs.upcall && (rpm -q cifs-utils 2>/dev/null || dpkg -l cifs-utils 2>/dev/null)
# Is the default cifs.spnego request-key rule present?
cat /etc/request-key.d/cifs.spnego.conf 2>/dev/null
# Are unprivileged user namespaces enabled?
sysctl user.max_user_namespaces kernel.unprivileged_userns_clone 2>/dev/null
If all three are true, you're vulnerable to the public PoC. Apply one of the mitigations above immediately.
Patch Status
Disclosed: May 28, 2026 (after embargo with linux-distros)
Upstream fix: Queued for stable kernel backports. Commit 3da1fdf4efbc is public and has been for over a week.
Distribution status (as of May 28, 2026):
- Red Hat (RHEL) kernel patches: Rolling out
- Ubuntu/Debian: Rolling out
- SUSE: Rolling out
- Oracle Linux: Rolling out
- Amazon Linux: Rolling out
Rebootless patches: KernelCare patches are deployed for EL8/EL9, Ubuntu, and Debian. Apply with:
kcarectl --update
CVE: Pending assignment at publication time.
Why This Matters More Than a Typical Kernel Bug
- Default installation: Most affected distros ship cifs-utils by default or enable unprivileged namespaces without asking
- No special privileges required: Any unprivileged local user can exploit
- Reliable exploitation: The public PoC works reliably on vulnerable systems
- 19-year latency: The underlying code has been in the kernel since 2007, so every kernel in that range has the vulnerability
- Discovered via ML: The vulnerability was found using LLM-assisted analysis of kernel object graphs, suggesting more vulnerabilities might be hiding in similar trust boundaries
If You Can't Patch Immediately
- Apply the mitigation (override request-key rule, or disable unprivileged namespaces, or uninstall cifs-utils)
- Monitor for exploitation attempts: Check
/var/log/auth.logand/var/log/sudofor unexpected privilege escalations - Plan the patch: Queue it for the next maintenance window
- Test first: Verify the kernel patch doesn't break your workload before rolling out widely
Most distributions should have patches available by early June 2026. Don't delay beyond that.
Real-World Context
The exploit was discovered using machine learning-assisted vulnerability discovery (LLM reasoning over kernel object graphs). This is a sign that more vulnerabilities like this—bugs lurking in trust boundaries between kernel and userspace—are likely to be discovered.
The fix is tiny (four lines). The exposure is broad (19 years of kernel versions). The practical impact depends entirely on whether three things are present: cifs-utils, unprivileged namespaces, and LSM policy that allows it.
This is a good reminder to:
- Understand what your distributions ship by default
- Know which system calls are available to unprivileged users
- Review privilege boundaries regularly
References
- oss-security mailing list: CIFSwitch disclosure (May 28, 2026)
- Linux kernel CIFS code (fs/smb/client/cifs_spnego.c)
- Upstream fix commit: 3da1fdf4efbc
- KernelCare advisory
- cifs-utils request-key configuration
- Linux kernel keyrings documentation
- Unprivileged user namespace documentation