TL;DR
- The CIFSwitch disclosure thread hit oss-security today, on the heels of Asim Manizada's writeup and PoC. It's a local root on Linux boxes that have cifs-utils installed with its default
cifs.spnegorequest-key rule and unprivileged user/mount namespaces enabled. No SMB server, no network — the whole exploit lives on the local box. - The bug: the kernel CIFS module lets an unprivileged process hand the kernel a forged
cifs.spnegokey description carrying attacker-chosenpid,uid,creduid, andupcall_target. The kernel runscifs.upcallas root, which trusts those fields, joins the attacker's namespaces onupcall_target=app, and does NSS lookups there — so a malicious/etc/nsswitch.confpluslibnss_*.so.2in your private mount namespace getsdlopen'd inside the root helper. The vulnerable path has existed since thecifs.spnegokey type was introduced in 2007. - Kernel fix: commit
3da1fdf4efbc— "smb: client: reject userspace cifs.spnego descriptions" — adds a.vet_descriptionhook that rejects anycifs.spnegorequest whose credentials don't match the kernel's private SPNEGO credential. If you can't take the kernel fix yet, the cheapest mitigation is to stop unprivileged namespaces or pull thecifs.spnegorequest-key rule.
The upcall is the trust boundary, and it was pointing the wrong way
Kerberos auth for CIFS mounts needs a userspace helper. The kernel can't do the SPNEGO/GSSAPI dance itself, so when it needs a ticket it fires a request-key upcall: it constructs a key of type cifs.spnego with a description string, and request-key matches that against /etc/request-key.d/cifs.spnego.conf and runs cifs.upcall — as root — to fill in the key.
The design assumption is that the kernel writes that description. CIFSwitch breaks the assumption: an unprivileged user can call request_key("cifs.spnego", <attacker string>, ...) directly and hand the helper a description the kernel never authored. The description carries fields the helper trusts — pid, uid, creduid, and crucially upcall_target.
When upcall_target=app, vulnerable cifs.upcall versions enter the calling process's namespaces to resolve names the way that process would — reasonable on its face, since the helper wants to look up the right principal for the right user. But "the calling process" is now the attacker. The root helper joins the attacker's private mount namespace, then performs NSS lookups. The attacker has staged a /etc/nsswitch.conf and a libnss_*.so.2 in that namespace; glibc dlopens the attacker's shared object inside the root process. That's the switch in CIFSwitch — root execution, flipped on a name-service lookup.
Why it's stock-exploitable, not theoretical
The preconditions are mundane:
- cifs-utils installed with the default
cifs.spnegorequest-key rule (the package ships it). - CIFS kernel module loadable or built in (an unprivileged user can often trigger the autoload).
- Unprivileged user/mount namespaces enabled — the default on most desktop distros.
- No confining LSM policy blocking the helper's namespace join or the
dlopen.
Manizada lists stock-exploitable targets including Linux Mint 21.3 / 22.3, CentOS Stream 9 GNOME, Rocky Linux 9 Workstation, AlmaLinux and SLES variants, and several Kali builds. Many more become exploitable the moment someone apt install cifs-utils to mount a share — which is exactly the box where someone mounts SMB shares. Distro vendors (Rocky/CIQ, CloudLinux) are already publishing CIFSwitch mitigation notes.
This is the same shape as a recurring Linux local-root class: a root-run helper that trusts a context an unprivileged caller controls. The long line of dlopen-from-attacker-controlled-path bugs (the libnss and LD_* lineage, and filesystem-layer escalations like Qualys' 2021 Sequoia) rhyme with this: the privilege boundary is a process that does name resolution on behalf of a less-privileged caller, and the caller gets to define what "resolution" loads. The uncomfortable part of CIFSwitch is its age — the vulnerable cifs.spnego path has been there since 2007, so this isn't a regression in a recent rewrite; it's a trust assumption that sat unexamined for the better part of two decades.
What to do
The fix is upstream as 3da1fdf4efbc — a .vet_description hook that only accepts a cifs.spnego description when CIFS is using its private SPNEGO credential to request the key, so a forged upcall never reaches the helper. Take the patched kernel when your distro ships it; track your distro's CIFSwitch/cifs.spnego entry for the backport.
If you can't reboot into a fixed kernel today, pick whichever of these fits the box:
- Drop unprivileged user namespaces where you don't need them:
sysctl kernel.unprivileged_userns_clone=0(Debian/Ubuntu) oruser.max_user_namespaces=0. This kills the namespace-staging half of the exploit and a lot of other local-root primitives with it. Scope: breaks rootless containers and some sandboxes, so it's a fleet-policy call, not a blanket default. - Remove the request-key rule if the host never does Kerberos CIFS mounts: clear
/etc/request-key.d/cifs.spnego.confso the kernel has nothing to upcall to. Scope: breakssec=krb5mounts; harmless on hosts that only dosec=ntlmsspor no SMB at all. - Confine the helper: an AppArmor/SELinux policy that denies
cifs.upcallthe namespace-join and arbitrarydlopenblunts the payload even on an unpatched kernel.
The reader action here is concrete: on any multi-user Linux host with cifs-utils, either you've taken the kernel fix or you've turned off unprivileged namespaces. Servers that mount SMB shares and hand out shell accounts are the ones to check first.
Sources
- Asim Manizada, CIFSwitch writeup — https://heyitsas.im/posts/cifswitch
- Proof-of-concept — https://github.com/manizada/CIFSwitch
- oss-security disclosure thread (2026-05-28) — https://www.openwall.com/lists/oss-security/2026/05/28/2
- Kernel fix
3da1fdf4efbc, "smb: client: reject userspace cifs.spnego descriptions" — https://github.com/torvalds/linux/commit/3da1fdf4efbc490041eb4f836bf596201203f8f2