Il n’y a plus de « vendredi bleu »
(brendangregg.com)- La panne mondiale de Windows du 19 juillet 2024 est un cas où une mise à jour de pilote kernel d’un produit de sécurité a provoqué une lecture mémoire incorrecte, entraînant des écrans bleus et des boucles de démarrage
- eBPF s’exécute dans le kernel, mais grâce à un vérificateur et à un sandbox, il rejette le code dangereux, et est conçu pour empêcher qu’un seul programme fasse planter tout le système
- Linux intègre déjà eBPF, et lorsque eBPF for Windows de Microsoft sera prêt pour la production, les logiciels de sécurité Windows pourront eux aussi migrer de la même manière
- De grands groupes technologiques comme Google, Meta et Cisco, ainsi que des startups de sécurité fondées sur eBPF, étendent leurs produits de sécurité et leurs systèmes de détection en tirant parti de la vitesse, de la visibilité profonde et des garanties de sûreté
- Les entreprises qui achètent des logiciels commerciaux incluant des pilotes kernel ou des modules kernel peuvent faire du support eBPF une exigence vis-à-vis des fournisseurs, dès maintenant sur Linux et bientôt sur Windows
Les risques du code kernel révélés par la panne Windows du 19 juillet
- La panne du 19 juillet 2024 a constitué un cas sans précédent illustrant les risques intrinsèques de la programmation kernel
- Des ordinateurs Windows dans le monde entier ont subi des écrans bleus (blue screen of death) et des boucles de démarrage, provoquant des perturbations dans des hôpitaux, compagnies aériennes, banques, supermarchés et chaînes de télévision
- La cause était une mise à jour de configuration (config update) d’un produit de sécurité largement utilisé, qui incluait un pilote kernel pour les systèmes Windows
- Après la mise à jour, le pilote kernel a tenté de lire une zone mémoire incorrecte, et ce type d’erreur peut faire planter le kernel
Les plantages qu’eBPF peut empêcher
- eBPF n’est plus seulement un acronyme, mais un environnement d’exécution kernel sécurisé comparable au runtime JavaScript sécurisé intégré à un navigateur web
- Les utilisateurs de Linux ont probablement déjà eBPF sur leur système, car eBPF a été intégré au kernel Linux il y a plusieurs années
- Les programmes eBPF sont limités de façon à ne pas pouvoir faire planter l’ensemble du système
- Un vérificateur (verifier) logiciel contrôle leur sûreté
- Le programme s’exécute en pratique dans un sandbox
- Si le vérificateur détecte du code non sûr, le programme est rejeté et ne s’exécute pas
- Le vérificateur de l’implémentation Linux se compose de plus de 20 000 lignes de code, avec des contributions de l’industrie comme Meta, Isovalent et Google, ainsi que du monde académique comme Rutgers University et University of Washington
- Le renforcement de la sécurité, la faible consommation de ressources et la prévention des plantages sont les principaux avantages d’eBPF
Possibilités d’adoption sur Linux et Windows
- L’entreprise de sécurité à l’origine de cette panne était déjà en cours d’adoption d’eBPF sur ses systèmes Linux
- Lorsque le support eBPF pour Windows de Microsoft sera prêt pour la production, les logiciels de sécurité Windows pourront eux aussi être portés vers eBPF
- Un agent de sécurité Windows migré vers eBPF prendra une forme qui ne pourra pas provoquer de plantage du kernel Windows
Adoption par l’industrie de la sécurité et les grands groupes technologiques
- Les startups de sécurité fondées sur eBPF, comme Oligo et Uptycs, ont récemment mis en avant, à la lumière de cette panne, les avantages d’une migration vers eBPF
- Les grands groupes technologiques adoptent eux aussi eBPF pour la sécurité
- Cisco a acquis la startup eBPF Isovalent et a présenté Cisco Hypershield, un fabric destiné à l’application des politiques de sécurité et au monitoring
- Google et Meta s’appuient sur la vitesse d’eBPF, sa visibilité profonde et ses garanties de sûreté pour détecter et bloquer des activités malveillantes à grande échelle
- eBPF est aussi utilisé en dehors de la sécurité, notamment pour le networking et l’observability
Limites d’eBPF et compléments opérationnels
- Le pire qu’un programme eBPF puisse faire est de consommer davantage de ressources que souhaité, comme des cycles CPU ou de la mémoire
- Il ne bloque pas forcément le code inefficace, mais il empêche les problèmes graves qui conduisent à un plantage du système
- eBPF reste une technologie récente, et du code de gestion a déjà présenté des bugs ; on peut citer un cas récent de kernel panic Linux découvert par la même entreprise de sécurité apparue dans l’actualité
- Corriger ce type de bug dans eBPF permet de diffuser le correctif à tous les fournisseurs eBPF et d’améliorer plus rapidement la sécurité globale
- Le risque de déploiement ne se résume pas à eBPF, et des pratiques opérationnelles complémentaires restent possibles
- tests canari
- déploiement progressif
- pratiques générales d’ingénierie de la résilience
Les changements que les acheteurs peuvent exiger
- L’aspect important de l’approche eBPF est qu’il s’agit d’une solution logicielle fournie nativement des deux côtés, sur les kernels Linux et Windows, et déjà adoptée pour ce cas d’usage
- Si une entreprise paie pour des logiciels commerciaux incluant des pilotes kernel ou des modules kernel, elle peut faire d’eBPF une exigence
- C’est possible dès aujourd’hui sur Linux, et cela le deviendra bientôt sur Windows
- Certains fournisseurs ont déjà adopté eBPF de manière proactive, mais pour d’autres, il faudra peut-être que des clients payants l’exigent
1 commentaires
Avis de Hacker News
Quand on regarde la liste des « hooks » fournis par eBPF pour Windows, elle semble assez éloignée de la réalité. Pour l’instant, cela se limite à peu près aux paquets entrants et aux opérations sur les sockets, comme si Microsoft s’attendait à ce que le Berkeley Packet Filter serve littéralement au filtrage de paquets.
Ce n’est pas la même chose que le filtrage d’I/O, la création/l’utilisation d’objets, ou les nombreux points auxquels des drivers comme ceux de CrowdStrike s’accrochent dans le noyau NT.
De plus, pour surveiller d’autres cochonneries tierces qui tournent dans l’espace noyau, l’antimalware doit lui aussi être dans le noyau. ELAM (early-launch anti-malware) charge d’abord le driver antimalware pour qu’il surveille le comportement des autres drivers ; il est très douteux qu’une telle chose soit possible avec eBPF.
Microsoft a encore un très long chemin à parcourir s’il veut remplacer les drivers antimalware en espace noyau par eBPF.
https://microsoft.github.io/ebpf-for-windows/ebpf__structs_8...
Par analogie, c’est comme si les gens faisaient leurs opérations bancaires sur un site web en JavaScript dans Google Chrome, tandis que Microsoft Edge disait : « nous ne prenons pas en charge JavaScript, veuillez télécharger et exécuter ce .EXE ». La question n’est pas tant de savoir « si » Microsoft prendra en charge JavaScript ou eBPF, mais plutôt « quand ».
Je n’ai pas envie de me disputer avec des gens comme Brendan Gregg, mais j’aimerais que les fournisseurs de ce secteur examinent toute la chaîne de défaillance de manière plus globale. Quand, trois jours après une panne, une proposition dit que « x résout le problème survenu à la date y », je deviens prudent.
Cela peut être exact, mais sans analyse, des angles morts peuvent subsister, et il peut aussi y avoir de nombreuses alternatives à examiner puis à écarter comme il convient.
En particulier, j’ai du mal à être d’accord avec l’idée que « le pire résultat négatif n’est qu’un gaspillage de CPU ». Cela peut être vrai pour certaines catégories de bugs, mais il existe largement assez de modes de défaillance où un ensemble de règles erroné peut sérieusement transformer un système en brique et rendre la récupération difficile.
Cela ne veut pas dire qu’un module de sécurité basé sur eBPF ne peut pas être le bon choix pour de nombreux fournisseurs ; il s’agit plutôt de comprendre quels risques on évite, lesquels on n’évite pas, et quelle partie de la chaîne de défaillance on traite.
https://opensource.microsoft.com/blog/2021/05/10/making-ebpf...
https://lwn.net/Articles/857215/
S’il y a de réelles inquiétudes, il existe aussi des canaux de discussion où donner son avis, et ils sont répertoriés sur GitHub.
https://github.com/microsoft/ebpf-for-windows
Il se peut que la réponse existe déjà ; sinon, cela peut y être traité.
Ce n’est pas exact. Si la structure du système exige la présence d’un certain morceau de code pour s’exécuter, alors, quand ce code est cassé, le système ne devrait tout simplement pas démarrer. Ignorer l’échec est étrange
Par exemple, si le code du driver d’un dispositif médical garantit un verrouillage de sécurité pour éviter de brûler quelqu’un, je choisirais que l’ensemble s’arrête plutôt qu’il fonctionne comme si de rien n’était avec la sécurité désactivée
Au final, même en descendant dans les couches, on retombe toujours sur le même problème
Je ne sais pas comment Linux se comporte réellement, mais on peut imaginer un monde où le comportement face à une entrée invalide serait configurable
Et cette affirmation n’est pas toujours vraie. Je suis d’accord dans le cas général, mais dans certains contextes il faut continuer à fonctionner. L’exemple qui me vient immédiatement est l’ordinateur de guidage d’un atterrisseur automatique sur Mars. Le délai aller-retour avec la Terre est trop long pour transférer la responsabilité
Si l’on s’arrête, on s’écrase ; mais si l’on fait au mieux dans un état endommagé, on ne fera probablement que s’écraser, donc cette option peut être préférable
Si tout le système d’exploitation devient une brique, il faut qu’un technicien IT intervienne physiquement pour le réparer, ce qui est un problème bien plus grave. Sinon, il aurait suffi de mettre à jour le driver défectueux
Une voiture ne refuse pas non plus de démarrer parce qu’il n’y a plus de liquide lave-glace
La plupart des organisations touchées vendredi auraient préféré une légère hausse du risque d’attaque par malware ou d’usage non autorisé pendant 24 heures à l’effondrement IT complet qu’elles ont effectivement subi
En outre, ce bug ne devait pas nécessairement provoquer un écran bleu. Le système aurait pu continuer à tourner dans un état indéfini, avec des conséquences illimitées
Avec eBPF, on peut au moins détecter une partie des erreurs possibles et prendre une décision de gestion du risque en fonction du résultat
Pour mettre à jour, l’appelant doit appeler une autre fonction ; la responsabilité incombe donc à l’appelant, et non à quelqu’un capable de toucher indirectement au noyau
S’il n’existe pas de fonction correspondant au hash indiqué, elle ne peut pas être appelée ; et même si elle existe, elle ne peut pas être appelée autrement que de la façon prévue, ce qui donne la propriété recherchée de « fonctionner parfaitement ou ne pas fonctionner du tout »
De plus, la réaction à un état invalide ne doit pas forcément être de « l’ignorer ». On pourrait désactiver les connexions utilisateur limitées ou éteindre l’écran
Si la crainte est qu’un malware puisse exploiter cela, je me demande s’il est vraiment judicieux de croire que le système lui-même peut gérer la situation alors que le malware est déjà en mesure de modifier les fichiers disque de l’antivirus
Il peut être plus sûr de le signaler à une couche de sécurité supérieure et de laisser des systèmes externes désactiver ou limiter l’accès réseau. Mieux encore, ces mesures n’exigent qu’un droit d’observation, pas le droit d’intervenir sur le système, ce qui réduit aussi la probabilité que l’antivirus lui-même devienne un chemin d’attaque pour le malware ou la cause de ce type de bug
eBPF est excellent, il sert à de nombreux usages et peut améliorer beaucoup de choses, mais dire qu’« une mauvaise mise à jour logicielle ne fera pas planter l’ordinateur » me semble exagéré
Même en supposant que BPF lui-même n’ait pas de bug, le périmètre des hooks noyau est assez large ; ces hooks appellent du code eBPF, et ce code peut à son tour appeler le noyau
https://www.man7.org/linux/man-pages/man7/bpf-helpers.7.html
En particulier, bpf_probe_read_kernel() est très utilisé, mais il n’est pas sûr. Il fait beaucoup d’efforts pour éviter les OOPS ou les crashs, mais il est loin d’être parfait
Dans le reste de la liste, il y a aussi beaucoup de choses qui peuvent facilement casser le système, même sans provoquer réellement d’oops ou de panic
Et s’il s’agit d’un outil qui détecte et bloque les « comportements malveillants » en espace utilisateur, il peut aussi commencer à tout considérer comme malveillant et rendre l’ordinateur inutilisable
Par ailleurs, eBPF n’a pas de véritable modèle de sécurité côté espace utilisateur. L’attachement effectif d’un programme eBPF se fait via l’appel système bpf(), et non par une opération de droits raisonnable sur l’objet noyau auquel il s’attache ; il n’existe aucun mécanisme pour confiner à l’intérieur d’un conteneur l’eBPF utilisé par ce conteneur. bpf_probe_read_kernel() peut, par nature, lire toute la mémoire du noyau
Ce qui rend donc eBPF meilleur que du code C noyau classique, c’est quelque chose d’analogue à écrire le code dans un langage sûr avec une surface d’API unsafe limitée. C’est une grosse amélioration pour ce type de tâche, mais ce n’est certainement pas parfait
On dit aussi que le vérificateur est strict et que l’implémentation Linux dépasse les 20 000 lignes, mais le vérificateur est absurdement complexe. Je préférerais voir une base fondée sur des méthodes formelles plutôt que 20 000 lignes de logique écrites à la main
L’affirmation selon laquelle « les programmes eBPF sont soumis à des contrôles de sûreté par un vérificateur logiciel et s’exécutent en pratique dans une sandbox, ils ne peuvent donc pas faire planter tout le système » me laisse perplexe.
L’un des objectifs d’un système d’exploitation n’est-il pas de surveiller les logiciels ? Je sais que c’est un problème lié au système d’exploitation lui-même, mais si l’on ajoute une couche pour surveiller le surveillant, ne faut-il pas au final surveiller aussi cette couche ?
Ne pourrait-on pas choisir la réduction de la complexité, plutôt que de croire naïvement qu’une nouvelle complexité sera meilleure à long terme ?
L’ancienne méthode consistait à charger un pilote noyau, à placer des hooks sur quantité d’appels système, et à prier pour que rien ne casse. En cas d’erreur, cela peut provoquer une panic, même si Linux est assez robuste.
L’approche eBPF ressemble davantage à demander les informations voulues au moyen d’instructions propres à eBPF.
Un aperçu de son fonctionnement se trouve ici : https://ebpf.io/what-is-ebpf/
Cela ressemble à une belle technologie, mais le vrai problème grave est dans la partie disant qu’on peut aussi utiliser « des méthodes d’atténuation des risques de déploiement logiciel comme les tests canari, les déploiements progressifs et l’ingénierie de la résilience ».
Il n’est pas nécessaire d’avoir une nouvelle technologie pour mettre en œuvre une gestion de la qualité de base, conforme aux standards du secteur.
Pour commémorer cet incident, on pourrait commencer à ne plus travailler le vendredi. Si les gens travaillaient avec moins de pression et avaient davantage de temps pour s’arrêter, réfléchir à la façon dont les choses évoluent et à l’influence qu’ils peuvent avoir sur cette évolution, les dégâts auraient peut-être été moindres.
Le fait que le vérificateur de l’implémentation Linux dépasse les 20 000 lignes et ait reçu des contributions de l’industrie et du monde universitaire ne me rassure pas, au contraire. La surface d’attaque supplémentaire est déjà un problème, mais qui peut garantir une base de code aussi vaste ?
J’ai l’impression que le vérificateur WebAssembly est beaucoup plus simple.
Si le filtre est chargé au démarrage et place des hooks partout, un seul bug peut verrouiller le système au point qu’il devienne impossible à manipuler ou à corriger. Par exemple, ce serait le cas si une liste d’autorisation vide était chargée, ce qui reviendrait à transformer une boucle de démarrage en une autre forme de déni de service.
Si Microsoft plaçait les éléments essentiels à la récupération dans une liste d’autorisation codée en dur, cela pourrait faciliter la correction des bugs de ce type d’outils, mais jusqu’au déploiement du correctif, le système pourrait rester allumé tout en étant inutilisable, ce qui constituerait en pratique un temps d’arrêt.
L’article de blog dit qu’« eBPF est immunisé contre ce type de crash ».
J’ai cherché, mais je n’ai rien trouvé de certain, et il me semble toujours possible de casser quelque chose. J’aimerais qu’un expert eBPF explique cette affirmation. La meilleure ressource que j’ai trouvée est celle-ci : https://stackoverflow.com/questions/70403212/why-is-ebpf-sai...