Meltdown, Spectre and Rowhammer -- 2018 sera une année chaude pour la sécurité informatique (et pour Intel)

Introduction

Si les abstractions sont utiles en général, et en informatique en particulier, l'informatique peut difficilement être considérée dans un modèle en couche: les interactions entre couches sont nombreuses, et un seul bit corrompu par un effet de bord d'une couche supérieure peut avoir des résultats catastrophiques au travers de toutes les abstractions.

Trois vulnérabilités actuelles exposées ci-dessous montrent ce problème et peut-être la nécessité de design de processeurs soumis à la revue de tiers ou à la communauté open source.

En effet, ces vulnérabilités mettent à mal l'isolation offerte par le matériel, que cela soit

  • le confinement offert par les logiciels (Sandbox Javascript, JVM Java)
  • le confinement offert par le MMU entre user-space et kernel-space
  • la virtualisation, quelque soit le degré d'isolation (container -> virtualisation de CPU)

P.ex. sur plateforme Android, les applications sont confinées au sein d'une JVM (sauf le code natif), puis par le kernel. Potentiellement ces vulnérabilités permettent d'aller lire, voire modifier, n'importe quelle valeur de n'importe quel processus ou du kernel. De même dans le cloud, vos données peuvent être lues, voire modifiées, par un autre client de ce cloud qui par hasard s'exécute également sur la même machine physique. Enfin tout ordinateur desktop ou mobile peut être attaqué par une violation du confinement de la Sandbox Javascript.

Bien sûr, des work-arounds sont entrain d'être installés, toutefois certains de ces problèmes sont suffisamment graves pour nécessiter des changement de design des processeurs à l'avenir, et certains (Rowhammer, Spectre) ne semblent pas corrigeables actuellement.

On connaissait déjà des vulnérabilités de bit-flipping (Rowhammer) et de devinage de clés AES par abus de cache en Javascript, mais ce qui vient d'être découvert est du lourd!

Bases théoriques

MMU unité du processeur permettant de gérer la mémoire virtuelle; elle est notamment utilisée pour séparer complètement l'adressage d'un processus à l'autre, ou rendre en lecture seule certaines parties
adressage virtuel les adresses mémoire accessibles par un processus donné sont limités à son adressage virtuel, qui est associé par MMU à de la RAM physique
speculative execution l'idée qu'en cas de branchement (par exemple une instruction similaire à un if), le processeur peut lancer l'exécution d'une branche à l'avance, en ne conservant les résultats que si cette branche est vraiment valide: cela augmente, par parallélisation (pipeline), la performance des processeurs modernes
cache une unité qui permet d'accélérer l'accès à la mémoire en stockant des parties de celles-ci dans le processeur (CPU), au besoin; se basant sur le principe de la localité d'exécution

Les vulnérabilités

Globalement, ces vulnérabilités ne sont exploitables que si du code de tiers tourne sur votre machine (ou, d'autres machines virtuelles de tiers côte-à-côte aux vôtres sur une même infrastructure, aka le cloud).

Sur une machine personnelle, si le code que vous tournez est signé.

Sur un smartphone ou sur le cloud, c'est plus ennuyeux.

Dans tous les cas, si un buffer overflow est possible, menant à du code exécutable, on a un plus gros problèmes qu'avec ces vulnérabilités: il reste important de mettre à jour, et les développeurs doivent utiliser les techniques anti buffer overflow (non executable stack, randomized user and kernel addresses, etc).

Meltdown

En utilisant une propriété des processeurs modernes, l'exécution spéculative, il est facile, sur processeur Intel datant de moins de dix ans, d'accéder en lecture à des données de l'ensemble de l'adressage virtuel d'un processus, même lorsque des règles du MMU interdisent l'accès.

Comme pour des raisons de performance, les données du kernel (le système d'exploitation de base, privilégié) sont intégrées à l'adressage virtuel de chaque processus (p.ex. en Linux 32 bits: 3 GB propre à chaque processus, plus 1 GB pour le kernel), toutefois inaccessibles par des règles de MMU (techniquement: page mappée mais non accessible), cela signifie que tout processus utilisateur peut maintenant aller lire des données privées du kernel, ce qui est une attaque de priviledge escalation.

C'est un bug de processeur, qui ne peut pas être corrigé par microcode par Intel (sauf sur quelques modèles récents). Le principe est que l'exécution spéculative va précharger des caches en violant les règles d'accès du MMU, et on pourra ensuite accéder aux données des caches.

L'impact est principalement pour les fournisseurs de service cloud (Javascript Sandbox, JVM, container ou virtualisation lourde): Google, Amazon, Microsoft (Azure) ainsi que les plus petits comme Hetzner, Exoscale, etc.

Si vous tournez du code auquel vous faisez confiance sur votre propre infrastructure, il n'est pas nécessaire d'installer le work-around. Par contre, avec du code C ou C++ ou tout code produisant du code machine (JIT compiler Java p.ex.) on peut imaginer une attaque permettant de lire l'ensemble des données du processus, de la machine virtuelle ainsi que d'autres machines virtuelles du même serveur du cloud, d'où la panique!

Le work-around logiciel (mise à jour du kernel) est d'isoler complètement l'address-space du kernel et de chaque processus. Avec une pénalité [1] évaluée de 5 à 30 pourcent sur la performance CPU. Ce work-around a été publié aujourd'hui sur GNU/Linux, et sera probablement disponible la semaine prochaine sous Microsoft. Apple est également concerné (desktop Intel), mais aussi sur les mobiles iOS (processeur ARM-compatible, également touché). Les AMD ne sont pas touchés par ce bug.

[1] chaque appel système (du processus au kernel) doit maintenant reconfigurer le MMU, et les caches CPU doivent être effacés. Une application faisant beaucoup d'appels kernel va être plus touchée qu'une application de calcul mathématique entièrement en user-space, n'utilisant que des bibliothèques user-space comme la libm ou la libc. Toutefois, c'est plus performant si votre CPU supporte les PCIDs, qui permettent d'associer une partie de cette configuration à un identifiant modifiable uniquement par le kernel.

  • Installation patch Meltdown ce vendredi soir 12 janvier 2018, on semble voir une augmentation de la charge CPU système (et de la charge totale), assez faible car ce système a les PCID:
    cpu-week.png

Spectre

Cette vulnérabilité a l'inconvénient de toucher quasi tous les types de processeur (contrairement à Meltdown), et en plus d'être difficilement patchable. Son principe est de mesurer le temps que prennent certaines instructions, et en particulier de dériver le temps qu'a pris l'exécution de branches spéculatives.

En bref, on construit une suite d'instruction ainsi qu'un branchement (saut, ou if) qu'on sait ne sera finalement pas exécuté en raison d'une condition non connue initialement du processeur. Le processeur va spéculer que la branche sera prise et va commencer l'exécution de celle-ci. Ensuite, après avoir remarqué que cette branche n'est pas nécessaire, il annulera ses effets. On a construit la branche pour contenir elle-même un branchement, lui-même dépendant d'une valeur que l'on n'est pas censé accéder, en s'assurant que les caches sont vides (p.ex. en accédant plein de données avant l'attaque). Le temps d'exécution de cette branche spéculative nous indiquera la valeur de la donnée après essais-erreurs (est-ce un zéro? est-ce un 1, etc).

La preuve de concept a été effectuée en Javascript à l'intérieur d'une Sandbox (container d'un navigateur) et a permis de lire l'ensemble de l'adress-space d'un processus.

Potentiellement, associé à Meltdown, cela permet avec du code Javascript dans une sandbox dans un processus navigateur dans une machine virtuelle de lire l'ensemble des données de la machine réelle et de toutes les machines virtuelles associées. Sans Meltdown, cela permet de sortir d'une Sandbox.

Work-around: Firefox a modifié la gestion des timers (compteurs de temps) de sa Sandbox Javascript pour la rendre moins précise, ce qui devrait rendre cette attaque beaucoup moins facile dans Firefox 57.0.4. En effet, le Javascript est un des rares cas où du code d'origine douteuse est téléchargé puis exécuté sur une machine (à part l'installation de logiciels, que l'on suppose signés et fournis par des développeurs auxquels on fait confiance). En Firefox LSR (Long Support Release), le bug n'est pas présent, ou pas entièrement.

Rowhammer

Cette vulnérabilité déjà ancienne, que l'on croyait être limitée à la potentialité de créer des corruptions de bits sur des DRAM (mémoire physique la plus classique) permet en fait l'accès écriture à n'importe quelle adresse de l'espace virtuel, ce qui combiné à une des vulnérabilités ci-dessous la rend très ennuyeuse, en particulier vu qu'il s'agit d'un problème difficile à corriger sans coût.

En effet, les DRAM perdraient leurs données si elles n'étaient pas rafraîchies régulièrement: plus on les rafraîchit (par lecture automatique), plus on perd des cycles pour l'accès mémoire utile du CPU. Le bug est qu'avec des accès particuliers dans un ordre dépendant de l'agencement matériel, on peut faire changer des bits non logiquement reliés (pas même adresse) en utilisant des propriétés connues d'un rafraîchissement économiquement supportable.

Même sans Meltdown ou Spectre, elle permet de modifier n'importe quelle valeur d'une machine: donc par exemple de s'attribuer des privilèges.

Références

clarification entre Spectre, Meltdown, et les variantes montrées par Google Project Zero

màj de microcode Intel

analogie avec une bibliothèque de l'attaque Meltdown

-- MarcSCHAEFER - 05 Jan 2018
Topic attachments
I Attachment Action Size Date Who Comment
cpu-week.pngpng cpu-week.png manage 29.8 K 15 Jan 2018 - 12:43 MarcSCHAEFER Installation patch Meltdown ce vendredi soir 12 janvier 2018
Topic revision: r11 - 16 Jan 2018, MarcSCHAEFER
 

Copyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding Foswiki? Send feedback