Pallier les failles Spectre et Meltdown : comment ça marche ?

Pour mieux comprendre l'impact des correctifs aux failles Spectre et Meltdown, il est essentiel de comprendre comment fonctionne ces failles ainsi que les mécanismes mis en oeuvre par les éditeurs et constructeurs pour tenter de les pallier.

Une semaine après l’officialisation des failles Spectre et Meltdown, l’industrie informatique continue à se débattre pour développer des parades efficaces aux deux failles tandis que les entreprises ont commencé à déployer les premiers correctifs et mises à jour de microcode proposés par les éditeurs et par les constructeurs.

Contrairement aux estimations initiales d’Intel, plutôt optimistes, les premiers correctifs ont un impact perceptible sur les performances et, dans certains cas, des effets secondaires inattendus.

Dans cet article en deux parties, LeMagIT fait tout d’abord le point sur les mécanismes des failles et des correctifs conçus par l’industrie. Une seconde partie est plus spécifiquement consacrée à l’analyse des impacts en matière de performances à partir des premiers retours des grands éditeurs de systèmes d’exploitation, des opérateurs de cloud et d’utilisateurs.

Pourquoi Meltdown affecte-t-il la performance

Pour comprendre l’impact sur les performances il faut d’abord revenir un peu en arrière sur les mécanismes des attaques et sur les mécanismes de fonctionnement de leurs correctifs, en commençant par la faille Meltdown, propre aux puces Intel.

Les processeurs modernes du fondeur supportent tous la gestion de la mémoire virtuelle. Les noyaux des systèmes d’exploitation tirent parti de cette capacité en mettant en place des tables, qui gèrent la correspondance entre les adresses virtuelles et les adresses physiques.

Les échanges de données entre le noyau et les applications tournant en mode utilisateur sont aussi contrôlés par un mécanisme de tables de correspondance. Mais avec une différence majeure : une page mémoire réservée au noyau n’est pas accessible par un processus en mode utilisateur, alors que le noyau a pour sa part accès à l’ensemble des pages.

Cette approche à base de tables de correspondance peut être consommatrice de cycles CPU lorsqu’il faut accéder à la mémoire. Aussi, pour accélérer la gestion de ces tables de correspondance, les processeurs modernes mettent en œuvre une technologie baptisée TLB (Translation lookaside buffer) pour accélérer la gestion de ces correspondances en hardware.

La TLB est un cache qui stocke les opérations les plus récentes entre mémoire virtuelle et mémoire physique. Parfois, notamment lors d’un changement de contexte,il est nécessaire de vider ces buffers (ce que l’on appelle un TLB Flush). Mais cette opération est effectuée aussi rarement que possible, car elle affecte lourdement les performances. Il faut en effet que le processeur rebâtisse les tables de correspondances pour retrouver une performance optimale.

Le problème spécifique aux processeurs Intel est qu’ils ne vérifient pas les droits d’accès aux plages d’adresses lorsqu’ils font de la mise en cache anticipée (prefetch) de données. Ce défaut peut être exploité par des programmes malicieux en mode utilisateur pour accéder à l’espace mémoire du noyau, ce qui est une faille catastrophique.

Le correctif logiciel KPTI créé pour contourner cette faille met l’espace mémoire du noyau hors de portée des processus en mode utilisateur en s’appuyant sur un niveau d’indirection additionnel. Le problème de cette approche est que lorsqu’un processeur en mode utilisateur doit faire appel au noyau, un changement de contexte doit être opéré pour accéder aux pages du noyau, ce qui nécessite de vidanger la TLB et se paie en performance par une centaine de cycles CPU additionnels sur une puce moderne.

Les applications faisant lourdement appel aux services du noyau peuvent donc voir leurs performances durement affectées. L’impact de ces changements de contexte peut être limité si le processeur supporte la technologie PCID, auquel cas on peut ne vidanger que la partie de la TLB correspondant à l’ID du processus applicatif concerné).

Spectre : une faille difficile à compler et aux impacts multiples

Dans le cas de la faille Spectre, la variante qui impacte le plus les performances est celle qui tente d’influencer le cache des prédicteurs de branchement des processeurs.

Pour mémoire, tous les processeurs modernes font de la prédiction de branchement afin d’améliorer leurs performances. Tous mettent en œuvre un cache (BTB ou Branch Target Buffer) et c’est ce cache qui peut être influencé par une attaque Spectre, ce qui peut amener à l’exécution d’instructions non prévues.

Plusieurs mécanismes sont mis en œuvre pour se protéger de l’attaque. Au niveau firmware, Intel a créé un microcode modifié qui réduit l’usage de la prédiction de branchement dans certains contextes.

Ce microcode met en œuvre trois mécanismes. Le code IBRS (Indirect branch restricted speculation) vise ainsi à protéger le noyau contre l’exécution d’instruction provenant d’un cache pollué par une application en mode utilisateur. Le code IBPB (indirect branch prediction barrier) permet quant à lui de réinitialiser l’état de la prédiction de branchement. Enfin STIBP (Single Thread indirect branch prediction » empêche un thread tournant sur un cœur CPU d’utiliser les informations de prédiction d’un autre thread tournant sur le même cœur.

Notons qu’AMD a mise en œuvre des fonctions équivalentes dans ses microcodes, mais que les puces Epyc et Rizen n’ont pas besoin d’IBRS leur prédicteur de branchement n’étant pas vulnérable selon la firme à la pollution de son cache.

Ces correctifs firmware sont associés à une nouvelle technique logicielle recommandée par Google baptisée « retpoline », dont l’objectif est de limiter l’aptitude d’un processus logiciel à influencer le comportement d’un prédicteur de branchement.

Mais sa mise en œuvre nécessite une recompilation des applications. Les principaux compilateurs libres ont déjà été mis à jour et ont été utilisés pour produire des versions amendées des navigateurs web. En attendant, les OS peuvent s’appuyer sur l’utilisation des techniques IBRS ou IPBP exposées par les nouveaux microcodes.

[Retrouvez l'analyse des pertes de performances dans la seconde partie de cet article]

Pour approfondir sur x86

Close