
Analyse und Abmilderung der Linux-Kernel-Copy-Fail-Sicherheitslücke (CVE-2026-31431), die die AF_ALG/splice-Page-Cache-Mutation ausnutzt, mit PoC-Checker, auditd-Erkennungsregeln und Kernel-Update-Überprüfung.
Dieses Projekt analysiert die Funktionsweise der Linux-Kernel-Sicherheitslücke Copy Fail (CVE-2026-31431) und vergleicht den Zustand vor und nach dem Patch mit Hilfe des nicht-destruktiven Checkers aus dem öffentlichen PoC-Repository.
Es führt keine tatsächliche Manipulation von setuid-Binärdateien oder der /etc/passwd-Datei durch, sondern konzentriert sich auf die sichere Überprüfung der Anfälligkeit auf Basis einer temporären testfile sowie auf die Analyse aus Erkennungs- und Abmilderungsperspektive.
Ziel dieses Projekts ist es nicht, einfach einen Exploit auszuführen, sondern zu verstehen, aus welcher Kombination interner Strukturen eine Linux-Kernel-Sicherheitslücke entsteht, und zusammenzufassen, wie sie aus betrieblicher Sicht erkannt und behoben werden kann.
Der Umfang ist wie folgt:
Analyse des Schwachstellenprinzips
↓
Analyse der PoC-Codestruktur
↓
Übung mit nicht-destruktivem Checker
↓
Vergleich vor/nach dem Patch
↓
Zusammenfassung der Erkennungs-/Abmilderungsmaßnahmen
In dieser Übung wurde nur vulnerable.c aus dem Repository copy-fail-c ausgeführt.
| Bereich | Vor dem Patch | Nach dem Patch |
|---|---|---|
| OS | Ubuntu 24.04.2 LTS | Ubuntu 24.04.4 LTS |
| Kernel | 6.8.0-53-generic | 6.8.0-134-generic |
| Benutzerkonto | Normaler Benutzer client | Normaler Benutzer client |
| Checker | vulnerable | vulnerable |
| Testmethode | Nicht-destruktive Prüfung basierend auf temporärer testfile | Erneute Ausführung desselben Checkers |
Kernelinformationen vor dem Patch:
Linux ubuntu-server 6.8.0-53-generic #55-Ubuntu SMP PREEMPT_DYNAMIC Fri Jan 17 15:37:52 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
Kernelinformationen nach dem Patch:
Linux ubuntu-server 6.8.0-134-generic #134-Ubuntu SMP PREEMPT_DYNAMIC Fri Jun 26 18:43:11 UTC 2026 x86_64 x86_64 x86_64 GNU/Linux
Zusammenfassung der Kernel-Paketänderungen:
- linux-image-6.8.0-53-generic 6.8.0-53.55
- linux-image-generic 6.8.0-53.55+1
+ linux-image-6.8.0-134-generic 6.8.0-134.134
+ linux-image-generic 6.8.0-134.134
+ linux-generic 6.8.0-134.134
+ linux-headers-generic 6.8.0-134.134
Copy Fail ist eine Sicherheitslücke, die durch die Kombination des AF_ALG-AEAD-Verarbeitungspfads im Linux-Kernel mit dem splice()-Zero-Copy-Mechanismus entsteht, wodurch der Page-Cache einer schreibgeschützten Datei fälschlicherweise als Schreibziel verwendet werden kann.
Die Kernkomponenten sind:
| Element | Rolle |
|---|---|
| Linux Page Cache | Kernel-Mechanismus zum Cachen von Dateiinhalten von der Festplatte im RAM |
splice() | Zero-Copy-Syscall, der Daten ohne Kopie in den Benutzerbereich als Referenz innerhalb des Kernels verbindet |
AF_ALG | Schnittstelle, die es dem Benutzerbereich ermöglicht, die Kernel-Crypto-API wie einen Socket zu verwenden |
| AEAD-In-Place-Verarbeitung | Optimierung, bei der der Eingabe- und Ausgabepuffer nicht getrennt, sondern im selben Puffer verarbeitet werden |
authencesn | Crypto-Template, das während der AEAD-Verarbeitung einen 4-Byte-Scratch-Schreibzugriff erzeugt |
Der Kernfluss der Sicherheitslücke ist:
Lesbare Datei
↓
Wird in den Linux Page Cache geladen
↓
Übergabe des Page-Cache-Referenz über splice() an den AF_ALG-Crypto-Pfad
↓
Durch AEAD-In-Place-Verarbeitung werden Eingabe- und Ausgabe-Scatterlist verknüpft
↓
Während der authencesn-Verarbeitung tritt ein 4-Byte-Scratch-Schreibzugriff auf
↓
Schreibzugriff erfolgt nicht in einen separaten Ausgabepuffer, sondern in den Page Cache
↓
Page-Cache-Mutation tritt auf
Das heißt: splice() übergibt die Page-Cache-Referenz, die AEAD-In-Place-Verarbeitung verknüpft Eingabe und Ausgabe über denselben Pfad, und authencesn löst den tatsächlichen 4-Byte-Schreibzugriff aus.
Die Struktur des in der Übung verwendeten Repositorys ist wie folgt:
copy-fail-c/
├── exploit.c
├── exploit-passwd.c
├── vulnerable.c
├── payload.c
├── utils.c
├── utils.h
├── Makefile
└── nolibc/
| Datei | Rolle | Verwendung in dieser Übung |
|---|---|---|
utils.c, utils.h | Implementierung des Page-Cache-Mutation-Primitives basierend auf AF_ALG/splice | Verwendet für Analyse und Ausführung von vulnerable |
vulnerable.c | Nicht-destruktives Tool zur Überprüfung der Anfälligkeit basierend auf temporärer testfile | Ausgeführt |
exploit.c | Variante zur Manipulation des Page-Cache einer setuid-root-Binärdatei | Nicht ausgeführt |
exploit-passwd.c | Variante zur Manipulation des Page-Cache von /etc/passwd | Nicht ausgeführt |
payload.c | Payload, die mit Root-Rechten ausgeführt wird | Nicht ausgeführt |
Makefile | Build-Automatisierung | Nur vulnerable-Target verwendet |
nolibc/ | Leichte libc-Alternative zum Bau kleiner statischer ELF-Payloads | Nur Analyse |
utils.cDer Kern von utils.c ist das Page-Cache-Mutation-Primitive der patch_chunk()-Familie. Diese Funktion verbindet den Page-Cache der Zieldatei über AF_ALG und splice() mit dem Crypto-Verarbeitungspfad und prüft bei anfälligen Kerneln, ob während der AEAD-Verarbeitung ein Teil des Page-Cache überschrieben wird.
vulnerable.cvulnerable.c greift nicht auf tatsächliche Systemdateien zu. Es erstellt eine temporäre testfile im aktuellen Verzeichnis und prüft, ob deren Page-Cache manipuliert wird.
In diesem Projekt wurde nur diese Datei ausgeführt.
Vor dem Kernel-Update wurden Betriebssystem-, Kernel- und Paketstatus aufgezeichnet.
mkdir -p ~/copyfail-mini/{before,after,logs}
cd ~/copyfail-mini
uname -a | tee before/uname.txt
cat /etc/os-release | tee before/os-release.txt
dpkg -l | grep -E 'linux-image|linux-headers|linux-generic|linux-virtual' | tee before/kernel-package.txt
git clone https://github.com/jihwan77/copy-fail-c.git
cd copy-fail-c
make clean
make vulnerable
In dieser Übung wurde nicht der vollständige make-Befehl zum Bau aller Exploit-Binärdateien verwendet, sondern nur das Ziel vulnerable.
./vulnerable > ../before/vulnerable-output.txt 2>&1
echo $? >> ../before/vulnerable-output.txt
cat ../before/vulnerable-output.txt
Ausgabe vor dem Patch:

Beurteilung:
exit code 100
→ Page-Cache-Mutation bestätigt
→ Funktionsweise des Copy-Fail-Primitives im Kernel vor dem Patch bestätigt
Nachdem die Ergebnisse vor dem Patch gespeichert wurden, wurde ein Ubuntu-Paketupdate durchgeführt.
sudo apt update
sudo apt full-upgrade -y
sudo reboot
Nach dem Neustart änderte sich der Kernel wie folgt:
Vorher: 6.8.0-53-generic
Nachher: 6.8.0-134-generic
cd ~/copyfail-mini/copy-fail-c
make clean
make vulnerable
./vulnerable > ../after/vulnerable-output.txt 2>&1
echo "exit_code=$?" >> ../after/vulnerable-output.txt
cat ../after/vulnerable-output.txt
Ausgabe nach dem Patch:

Ergebnisvergleich: