modules: add cifswitch (CVE-2026-46243, Asim Manizada's CIFSwitch)
release / build (arm64) (push) Waiting to run
release / build (x86_64) (push) Waiting to run
release / build (x86_64-static / musl) (push) Waiting to run
release / build (arm64-static / musl) (push) Waiting to run
release / release (push) Blocked by required conditions
release / build (arm64) (push) Waiting to run
release / build (x86_64) (push) Waiting to run
release / build (x86_64-static / musl) (push) Waiting to run
release / build (arm64-static / musl) (push) Waiting to run
release / release (push) Blocked by required conditions
CIFSwitch is the newest kernel-7-era LPE not already in the corpus: a
~19-year-old logic flaw in fs/smb/client/cifs_spnego.c where the
cifs.spnego request-key type accepts key descriptions created by
userspace (add_key(2)/request_key(2)) without verifying the request came
from the in-kernel CIFS client. The description's authority-bearing
fields (pid/uid/creduid/upcall_target) are trusted by the root cifs.upcall
helper; with user+mount namespace tricks an unprivileged user coerces
cifs.upcall into loading an attacker NSS module as root. Fixed upstream by
3da1fdf4efbc (merged 7.1-rc5); CWE-20; not in CISA KEV.
Takes the corpus to 42 modules / 37 CVEs.
🟡 honest port — full chain not VM-verified. detect() gates on the kernel
version (Debian backports 5.10.257/6.1.174/6.12.90/7.0.10) AND on the
cifs userspace path (cifs.upcall / cifs.spnego request-key rule), so a
vulnerable kernel without cifs-utils is PRECOND_FAIL not a false positive
(override via SKELETONKEY_CIFS_ASSUME_PRESENT=1/0). exploit() fires only
the non-destructive add_key(2) cifs.spnego probe (no upcall, loads
nothing, revoked immediately) and returns EXPLOIT_FAIL without a euid-0
witness — the namespace+NSS root-pop is not bundled until VM-verified.
--mitigate blocklists the cifs module; --cleanup reverts.
Wired everywhere: registry, Makefile, safety rank (86), 6 detect() test
rows (env-driven precondition override), CVE_METADATA.json + cve_metadata.c
+ KEV_CROSSREF.md (sorted insert, CWE-20/T1068/not-KEV), README + CVES.md
+ website counts (42/37) and a yellow module pill, RELEASE_NOTES v0.9.10,
verify-vm target (sweep pending). Credit: Asim Manizada. Version 0.9.10.
This commit is contained in:
@@ -70,6 +70,7 @@ extern const struct skeletonkey_module vsock_uaf_module;
|
||||
extern const struct skeletonkey_module nft_pipapo_module;
|
||||
extern const struct skeletonkey_module ptrace_pidfd_module;
|
||||
extern const struct skeletonkey_module sudo_host_module;
|
||||
extern const struct skeletonkey_module cifswitch_module;
|
||||
|
||||
static int g_pass = 0;
|
||||
static int g_fail = 0;
|
||||
@@ -803,6 +804,44 @@ static void run_all(void)
|
||||
&sudo_host_module, &h_sudo_host_1917,
|
||||
SKELETONKEY_VULNERABLE);
|
||||
|
||||
/* ── cifswitch (CVE-2026-46243) ──────────────────────────────
|
||||
* Version-gated on Debian backports 5.10.257 / 6.1.174 / 6.12.90 /
|
||||
* 7.0.10. The VULNERABLE/PRECOND_FAIL split below the fix depends on
|
||||
* whether the cifs.upcall userspace path is present; we drive that
|
||||
* deterministically with SKELETONKEY_CIFS_ASSUME_PRESENT (1=present,
|
||||
* 0=absent) so the rows don't depend on cifs-utils being installed on
|
||||
* the runner. Patched-kernel rows return OK before the probe, so they
|
||||
* need no override. */
|
||||
|
||||
/* patched branch (exact 6.12.90 backport) → OK regardless of cifs */
|
||||
struct skeletonkey_host h_ciw_61290 =
|
||||
mk_host(h_kernel_6_12, 6, 12, 90, "6.12.90-test");
|
||||
run_one("cifswitch: 6.12.90 (exact backport) → OK via patch table",
|
||||
&cifswitch_module, &h_ciw_61290,
|
||||
SKELETONKEY_OK);
|
||||
|
||||
/* 7.1.0 newer than every entry → mainline-inherited fix → OK */
|
||||
struct skeletonkey_host h_ciw_710 =
|
||||
mk_host(h_kernel_6_12, 7, 1, 0, "7.1.0-test");
|
||||
run_one("cifswitch: 7.1.0 above all backports → OK (mainline inherit)",
|
||||
&cifswitch_module, &h_ciw_710,
|
||||
SKELETONKEY_OK);
|
||||
|
||||
/* vulnerable kernel (one below 6.12.90) + cifs path present → VULNERABLE */
|
||||
struct skeletonkey_host h_ciw_61289 =
|
||||
mk_host(h_kernel_6_12, 6, 12, 89, "6.12.89-test");
|
||||
setenv("SKELETONKEY_CIFS_ASSUME_PRESENT", "1", 1);
|
||||
run_one("cifswitch: 6.12.89 + cifs.upcall present → VULNERABLE",
|
||||
&cifswitch_module, &h_ciw_61289,
|
||||
SKELETONKEY_VULNERABLE);
|
||||
|
||||
/* same vulnerable kernel but cifs path absent → PRECOND_FAIL */
|
||||
setenv("SKELETONKEY_CIFS_ASSUME_PRESENT", "0", 1);
|
||||
run_one("cifswitch: 6.12.89 but cifs-utils absent → PRECOND_FAIL",
|
||||
&cifswitch_module, &h_ciw_61289,
|
||||
SKELETONKEY_PRECOND_FAIL);
|
||||
unsetenv("SKELETONKEY_CIFS_ASSUME_PRESENT");
|
||||
|
||||
/* ── coverage report ─────────────────────────────────────────
|
||||
* Iterate the runtime registry (populated by skeletonkey_register_*
|
||||
* calls in main()) and warn for any module that was not touched
|
||||
|
||||
Reference in New Issue
Block a user