Les race conditions kernel sont parmi les vulnérabilités les plus complexes et les plus puissantes en exploitation système. Contrairement aux buffer overflows qui corrompent la mémoire par débordement, les race conditions exploitent les fenêtres temporelles entre deux opérations qui devraient être atomiques mais ne le sont pas. Les deux catégories principales — Double-Fetch (le kernel lit deux fois une valeur en mémoire partagée, l'attaquant la modifie entre les deux lectures) et TOCTOU (Time-of-Check-Time-of-Use, le kernel vérifie une condition puis agit dessus, l'attaquant modifie l'état entre la vérification et l'utilisation) — permettent l'escalade de privilèges, le contournement des vérifications de sécurité et la corruption de données kernel. Ce guide technique couvre les mécanismes d'exploitation, les techniques de synchronisation (race winning), les CVE historiques (Dirty COW, Dirty Pipe), les outils de détection et les primitifs avancés d'exploitation de race conditions dans le noyau Linux et Windows.
En bref
- Double-Fetch : le kernel lit deux fois une valeur userspace — l'attaquant la modifie entre les lectures
- TOCTOU : Time-of-Check-Time-of-Use — l'état change entre la vérification et l'utilisation
- Exploitation : timing manipulation, multi-threading, CPU pinning et userfaultfd
- CVE historiques : Dirty COW (CVE-2016-5195), Dirty Pipe (CVE-2022-0847), io_uring races
- Détection : KCSAN, Thread Sanitizer, analyse statique et fuzzing concurrentiel (Syzkaller)
Double-Fetch : Mécanisme et Exploitation
Un double-fetch se produit quand le kernel accède deux fois au même emplacement en mémoire userspace : une première fois pour vérifier (validation de taille, type, permissions) et une seconde fois pour utiliser la valeur. L'attaquant utilise un second thread pour modifier la valeur entre les deux accès :
// KERNEL CODE VULNÉRABLE (simplifié)
// Le kernel lit la taille depuis l'espace utilisateur DEUX FOIS
struct user_request __user *req = (void *)arg;
// 1ère lecture : vérification de la taille
if (copy_from_user(&size, &req->size, sizeof(size)))
return -EFAULT;
if (size > MAX_SIZE)
return -EINVAL; // Vérification OK
// ⚠️ FENÊTRE DE RACE — l'attaquant modifie req->size ici
// 2ème lecture : utilisation de la taille (implicite dans copy_from_user)
buf = kmalloc(size, GFP_KERNEL); // Alloue avec la taille vérifiée
if (copy_from_user(buf, req->data, req->size)) // ❌ Re-lit req->size !
// req->size peut maintenant être > MAX_SIZE → buffer overflow kernel
return -EFAULT;
TOCTOU : Time-of-Check-Time-of-Use
Les vulnérabilités TOCTOU surviennent quand le kernel vérifie une condition (check) puis agit dessus (use), mais l'état peut changer entre les deux opérations. L'exemple classique est la vérification d'accès à un fichier :
// TOCTOU classique sur le filesystem
// Thread 1 (programme setuid) :
if (access("/tmp/config", R_OK) == 0) {
// CHECK : l'utilisateur a le droit de lire /tmp/config
// ⚠️ FENÊTRE DE RACE
// Thread 2 : symlink("/etc/shadow", "/tmp/config")
fd = open("/tmp/config", O_RDONLY);
// USE : ouvre le fichier — mais c'est maintenant /etc/shadow !
read(fd, buf, sizeof(buf)); // Lit /etc/shadow avec les privilèges root
}
Dirty COW (CVE-2016-5195) : La Race Condition Légendaire
Dirty COW est la race condition kernel la plus célèbre : elle exploite une race dans le mécanisme de Copy-on-Write (COW) du gestionnaire de mémoire Linux. Quand un processus écrit dans une page COW, le kernel doit copier la page avant l'écriture. Dirty COW exploite une race entre le thread de fault handling et le thread d'écriture pour modifier directement la page originale (partagée) sans la copier — permettant l'écriture dans des fichiers en lecture seule, y compris /etc/passwd et les binaires setuid.
Dirty Pipe (CVE-2022-0847) : Race sur les Pipes
Dirty Pipe exploite un bug dans la gestion des pipes Linux : le flag PIPE_BUF_FLAG_CAN_MERGE n'est pas correctement initialisé quand un pipe buffer est recyclé depuis le page cache. L'attaquant peut écrire dans n'importe quel fichier lisible (même en lecture seule) via un pipe, sans aucune race condition temporelle — le bug est déterministe. Dirty Pipe est considéré comme encore plus puissant que Dirty COW car il est fiable à 100%.
Techniques de Race Winning
Gagner une race condition kernel nécessite un contrôle précis du timing entre les threads :
- CPU Pinning : utiliser
sched_setaffinity()pour forcer les threads attaquant et victime sur des cœurs CPU spécifiques, réduisant la variabilité de scheduling - userfaultfd : intercepter les page faults userspace pour bloquer le kernel au milieu d'un
copy_from_user()— agrandit la fenêtre de race à l'infini - FUSE (Filesystem in Userspace) : monter un filesystem FUSE et bloquer les opérations de lecture pour contrôler le timing des accès fichier du kernel
- io_uring : les opérations asynchrones io_uring créent naturellement des fenêtres de race dans le kernel
- Flooding / contention : saturer les caches, les locks ou les schedulers pour augmenter la latence entre les opérations kernel
userfaultfd : L'Arme Ultime pour les Races Kernel
// userfaultfd — contrôler le timing d'un copy_from_user kernel
#include <linux/userfaultfd.h>
#include <sys/ioctl.h>
// 1. Créer un userfaultfd
int uffd = syscall(SYS_userfaultfd, O_CLOEXEC | O_NONBLOCK);
// 2. Mapper une page et l'enregistrer avec userfaultfd
void *page = mmap(NULL, PAGE_SIZE, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
struct uffdio_register reg = {
.range = {.start = (unsigned long)page, .len = PAGE_SIZE},
.mode = UFFDIO_REGISTER_MODE_MISSING
};
ioctl(uffd, UFFDIO_REGISTER, ®);
// 3. Passer 'page' au syscall vulnérable
// Quand le kernel fait copy_from_user(page) → PAGE FAULT
// Le kernel se bloque et attend notre handler userfaultfd
// 4. Dans le handler (thread séparé) :
// - Modifier l'état kernel (autre thread/syscall)
// - Puis résoudre le fault en fournissant les données
struct uffdio_copy copy = {
.dst = (unsigned long)page,
.src = (unsigned long)malicious_data,
.len = PAGE_SIZE,
};
ioctl(uffd, UFFDIO_COPY, ©);
// → Le kernel reprend avec nos données malveillantes
Détection et Prévention
- KCSAN (Kernel Concurrency SANitizer) : détecteur de data races dynamique intégré au kernel Linux depuis 5.8
- Syzkaller : fuzzer kernel de Google qui génère automatiquement des séquences de syscalls concurrentes pour déclencher des races
- copy_from_user_once() : pattern kernel recommandé — copier les données userspace une seule fois dans un buffer kernel, puis utiliser uniquement le buffer kernel
- Restriction userfaultfd : Linux 5.11+ restreint userfaultfd aux processus avec CAP_SYS_PTRACE (sysctl vm.unprivileged_userfaultfd=0)
À retenir
- Les race conditions kernel exploitent les fenêtres temporelles entre opérations non-atomiques
- Double-fetch : le kernel lit 2x la mémoire userspace — l'attaquant modifie entre les lectures
- TOCTOU : l'état change entre la vérification (check) et l'utilisation (use) — bypass de permissions
- userfaultfd bloque le kernel au milieu de copy_from_user() — agrandit la fenêtre de race à l'infini
- Dirty COW et Dirty Pipe sont les race conditions kernel les plus célèbres — LPE fiable sur Linux
- KCSAN et Syzkaller détectent automatiquement les data races dans le kernel Linux
FAQ — Questions Fréquentes
Les race conditions kernel sont-elles exploitables de manière fiable ?
Historiquement non — les races étaient considérées comme non-fiables car dépendantes du timing CPU. Mais les techniques modernes (userfaultfd, FUSE, CPU pinning) permettent de contrôler le timing avec une précision suffisante pour une exploitation fiable. Dirty COW avait un taux de succès >90% avec la bonne configuration de threads. Dirty Pipe est déterministe (pas réellement une race condition temporelle).
Comment trouver des race conditions dans le kernel Linux ?
Les approches principales : Syzkaller (fuzzer kernel concurrentiel — le plus efficace), KCSAN (détection dynamique de data races pendant l'exécution), audit de code (rechercher les double-fetch dans copy_from_user et les TOCTOU dans les vérifications de permissions), et analyse statique (outils comme Coccinelle avec des patterns de détection de races).
userfaultfd est-il toujours disponible pour les attaquants ?
Sur les kernels récents (5.11+), userfaultfd nécessite CAP_SYS_PTRACE pour les processus non privilégiés si vm.unprivileged_userfaultfd=0 est configuré (défaut sur la plupart des distributions récentes). Cependant, l'alternative FUSE (Filesystem in Userspace) fournit des capacités similaires pour le contrôle de timing et est accessible sans privilèges spéciaux via fusermount.
Besoin d'un accompagnement expert ?
Nos consultants spécialisés en sécurité système et exploitation kernel vous accompagnent dans l'évaluation de votre posture de sécurité.
Contactez-nous📚 Articles connexes
🔗 Références externes

Besoin d'un expert cybersécurité ?
Audit, pentest, formation, IA — plus de 25 ans d'expérience, 100+ missions réalisées.
Télécharger cet article en PDF
Format A4 optimisé pour l'impression et la lecture hors ligne
À propos de l'auteur
Ayi NEDJIMI
Auditeur Senior Cybersécurité & Consultant IA
Expert Judiciaire — Cour d'Appel de Paris
Habilitation Confidentiel Défense
ayi@ayinedjimi-consultants.fr
Ayi NEDJIMI est un vétéran de la cybersécurité avec plus de 25 ans d'expérience sur des missions critiques. Ancien développeur Microsoft à Redmond sur le module GINA (Windows NT4) et co-auteur de la version française du guide de sécurité Windows NT4 pour la NSA.
À la tête d'Ayi NEDJIMI Consultants, il réalise des audits Lead Auditor ISO 42001 et ISO 27001, des pentests d'infrastructures critiques, du forensics et des missions de conformité NIS2 / AI Act.
Conférencier international (Europe & US), il a formé plus de 10 000 professionnels.
Domaines d'expertise
Ressources & Outils de l'auteur
Testez vos connaissances
Mini-quiz de certification lié à cet article — propulsé par CertifExpress
Articles connexes
Retours d’Expérience Pentest : 5 Missions Terrain Anonymisées
Plongez au cœur de 5 missions de pentest réelles et anonymisées : compromission Active Directory en 4h, chaîne IDOR+SSRF vers RCE sur un e-commerce, Red Team contre EDR CrowdStrike, audit cloud AWS avec exfiltration S3, et évaluation OT/ICS Modbus. Pour chaque mission : contexte, méthodologie détaillée, outils utilisés, chronologie, découvertes critiques et remédiations appliquées.
Nuclei vs Nessus vs Qualys : Scanners de Vulnérabilités Comparés
Comparatif des trois principaux scanners de vulnérabilités : Nuclei (open-source), Nessus (Tenable) et Qualys VMDR.
Burp Suite vs OWASP ZAP : Quel Scanner Web Choisir en 2026 ?
Comparatif Burp Suite Pro vs OWASP ZAP pour le pentest web en 2026. Prix, fonctionnalités, extensions et verdict d'expert.
Commentaires
Aucun commentaire pour le moment. Soyez le premier à commenter !
Laisser un commentaire