
Out-of-Bounds-Schreibzugriff im Linux-Kernel-FUSE-readdir-Cache (CVE-2026-31694): ein bösartiger FUSE-Server überschreibt eine Page-Cache-Seite um 24 Bytes. PoC plus ein unprivilegierter Local-Root-Exploit via /etc/passwd Page-Cache-Korruption. Nur innerhalb einer VM ausführen.
Eine fehlende Bereichsprüfung in fs/fuse/readdir.c:fuse_add_dirent_to_cache(). Ein
FUSE-Server gibt ein dirent mit namelen = 4095 zurück, das zu einem 4120-Byte-Datensatz
serialisiert wird. Der Kernel kopiert es in eine einzelne 4096-Byte-Page-Cache-Seite und
überläuft um 24 vom Server kontrollierte Bytes in die nächste physische Seite.
Dieses Repository enthält einen Marker-PoC für die Schreibprimitive und eine lokale
Privilegieneskalation, die den Überlauf auf die Page-Cache-Kopie von /etc/passwd
lenkt und root in ein passwortloses Konto verwandelt.
FUSE_NAME_MAX auf PATH_MAX - 1 machte den
readdir-Pfad erreichbar)51a8de6c50bf9 "fuse: reject oversized dirents in page cache" (einer
von fünf stabilen Backports)Der Überlauf ist ein Kernel-Schreibvorgang in die physische Seite, die direkt nach der FUSE-Cache-Seite liegt. Das Grooming zielt diesen Schreibvorgang auf eine ausgewählte Seite ab, ist jedoch probabilistisch. Bei einem Fehlschlag können die 24 Bytes eine nicht zusammenhängende Seite treffen:
Führen Sie es nur innerhalb einer Wegwerf-VM aus. Die Skripte hier führen den Exploit immer innerhalb von QEMU/KVM aus, niemals auf dem Host.
exploit.c der PoC und die LPE (einzelne Datei, statischer Build)
Makefile erstellt ./exploit (statisch)
vm/config.sh alle Pfade und Einstellungen (KERNEL_TREE bearbeiten)
vm/make_rootfs.sh erstellt das Ubuntu-24.04-Gast-Image (als root ausführen)
vm/build_vuln_kernel.sh erstellt ein verwundbares bzImage aus Ihrem Kernel-Baum
vm/run_vm.sh startet den Gast im Headless-Modus
vm/provision_guest.sh Einrichtung im Gast (läuft über ssh)
vm/run_in_vm.sh ein Befehl: booten, einrichten, ausführen, überprüfen
Host: Linux mit KVM (/dev/kvm vorhanden, Ihr Benutzer in der kvm-Gruppe) und:
qemu-system-x86_64, sshpass, gcc, makemake_rootfs.sh: debootstrap (und root)Sie benötigen außerdem einen Linux-Kernel-Quellbaum, um einen verwundbaren Kernel zu erstellen.
Bearbeiten Sie vm/config.sh. Der einzige Wert, den Sie setzen müssen, ist KERNEL_TREE: der Pfad
zu einem Linux-Quell-Checkout. Verwenden Sie eine Revision vor dem Fix 51a8de6c50bf9
(jeder Checkout von 6.15..7.0 hat den Fehler). Wenn der Baum den Fix bereits enthält,
entfernt build_vuln_kernel.sh den Schutz für den Build und stellt die Datei anschließend
wieder her. Alles andere (Speicher, CPUs, SSH-Port, Image-Pfade) hat einen
Standardwert, den Sie unverändert lassen können. Jeder Wert kann auch über die Umgebungsvariable
gesetzt werden, z.B. KERNEL_TREE=/path/to/linux vm/run_in_vm.sh.
Erstellen Sie das Gast-Image (Ubuntu 24.04, benötigt root für debootstrap):
sudo vm/make_rootfs.sh
Dies erstellt einen sudo-Benutzer test:test, eine serielle Konsole, SSH-Passwort-Authentifizierung
und fuse3.
Erstellen Sie den verwundbaren Kernel:
vm/build_vuln_kernel.sh
Ende-zu-Ende (booten, einrichten, Marker-PoC, LPE, uid 0 überprüfen):
vm/run_in_vm.sh
Manuell:
vm/run_vm.sh & # headless booten; Konsole geht nach vm/serial.log
make # den statischen Exploit erstellen
# ./exploit in den Gast kopieren, dann als Benutzer test:
./exploit --poc -n 20 # Markertest
./exploit # Aufwärmen, dann LPE
VM stoppen:
pkill -f bzImage-fuse-vuln
--poc nur Marker-Modus, keine Änderungen an /etc/passwd
-n N Anzahl der Durchläufe
(keine Argumente) 5 Aufwärmdurchläufe, dann bis zu 200 LPE-Versuche; bei Erfolg wird eine
passwortlose Root-Zeile in /etc/passwd geschrieben und Caches werden gelöscht
Der Marker-Modus gibt Treffer pro Durchlauf und eine Gesamtzahl aus, z.B. 20/20 (100.0%).
Der LPE-Modus gibt Warmup: 5/5 aus, dann eine Zeile LPE n/200 ... HIT!, ändert die
erste Zeile von /etc/passwd von root:x:0:0:root:/root:/bin/bash in
root::0:0:root:/root:/bin/sh, und ein anschließendes su -s /bin/sh root mit
einem leeren Passwort gibt uid 0 zurück.
Der readdir-Cache-Pfad kopiert jedes dirent in eine Page-Cache-Seite. Die Größenprüfung
fragt nur, ob das dirent in den verbleibenden Platz der aktuellen Seite passt; sie fragt
nie, ob das dirent überhaupt in eine Seite passt. Mit namelen = 4095 ist der
Datensatz 4120 Bytes groß, sodass die Kopie 24 Bytes über das Ende einer frischen Seite hinausläuft.
Der Exploit leert die per-CPU-Seiten-Freilisten (PCP), sodass der Allokator physisch
benachbarte Seiten aus Buddy-Splits ausgibt, und ordnet dann die readdir-Cache-Seite
und eine Opferseite als Nachbarn an. Für die LPE ist das Opfer die Page-Cache-Kopie
von /etc/passwd: Der 24-Byte-Überlauf überschreibt die Zeile von root, sodass das
Passwortfeld leer ist, und mit PAM nullok (Ubuntu-Standard) funktioniert su root
dann mit einem leeren Passwort.
Vollständiger Artikel: https://cyberstan.co.uk/fuse-readdir-oob/
Upstream gemeldet von Qi Tang und Zijun Hu; der Fix wurde von Samuel Page verfasst. Ich habe dies unabhängig gefunden und gemeldet. Die Upstream-Anerkennung und CVE-2026-31694 gehören ihnen. Der Fehler ist im Hauptentwicklungszweig und in den stabilen Bäumen behoben.
MIT, siehe LICENSE. Nur für Bildungszwecke und autorisierte Tests.