Ça semble sentir le roussi chez Intel. N’étant pas familier du bas niveau, je me demande quels usages seront touchés par la correction de cette faille ? On dit qu’on peut perdre jusqu’à 30% des capacités du processeur. Quelles puces ? Bref, si des personnes veulent bien vulgariser, je dirais pas non
D’après des gens plus calés que moi, ça touche les programmes qui font beaucoup d’appels systèmes. Pour le particulier, ça devrait être relativement indolore ; pour les professionnels, en particlulier dans le cas des bases de données, ça fera plus mal.
Actuellement les patchs sont déployés sur tous les processeurs x86, sans distinguo entre AMD et Intel. Donc concerné ou non, chaque processeur sera "ralenti" selon l’usage qui en est fait.
Le vrai problème se situe-t-il niveau performances ou sécurité au final ? Tout ça m’a l’air d’être soit très confus par manque de communication de la part d’Intel, soit du bruit pour pas grand-chose…
Actuellement les patchs sont déployés sur tous les processeurs x86, sans distinguo entre AMD et Intel. Donc concerné ou non, chaque processeur sera "ralenti" selon l’usage qui en est fait.
Le code du Patch linux kernel ne semble pas le désactivé par défaut (sauf si le kernel est booté avec l’option "nopti", et je n’ai actuellement ni un linux ni un processeur AMD pour voir ce qu’il met par défaut)
1
2
/* Assume for now that ALL x86 CPUs are insecure */
+ setup_force_cpu_bug(X86_BUG_CPU_INSECURE);
Une piste : http://people.oregonstate.edu/~jangye/assets/papers/2016/jang:drk-bh.pdf qui parle d’attaque par canaux auxiliaires.
Si j’ai bien compris, c’est le fait de prévenir d’une faille matérielle par des moyens logiciels qui cause des problèmes de performance assez indésirables.
Actuellement les patchs sont déployés sur tous les processeurs x86, sans distinguo entre AMD et Intel. Donc concerné ou non, chaque processeur sera "ralenti" selon l’usage qui en est fait.
Le code du Patch linux kernel ne semble pas le désactivé par défaut (sauf si le kernel est booté avec l’option "nopti", et je n’ai actuellement ni un linux ni un processeur AMD pour voir ce qu’il met par défaut)
1
2
/* Assume for now that ALL x86 CPUs are insecure */
+ setup_force_cpu_bug(X86_BUG_CPU_INSECURE);
AMD dit ne pas être touché par la faille. Donc correctif :
1
2
3
4
- /* Assume for now that ALL x86 CPUs are insecure */- setup_force_cpu_bug(X86_BUG_CPU_INSECURE);+ if (c->x86_vendor != X86_VENDOR_AMD)+ setup_force_cpu_bug(X86_BUG_CPU_INSECURE);
Apparemment, le parc des Mac tournant sous la dernière version de macOS est déjà à jour pour contrer la faille.
Et visiblement il n’y a pas eu trop de répercussion sur les perfs … en tout cas rien de notable à grosse échelle puisque c’est un sujet qui n’a pas surgi ces dernières semaines.
(Ça fait plaisir de savoir qu’Apple a pas trainé des pieds pour le correctif.)
J’ai pas mal potassé la seconde, elle semble plus intéressante techniquement. Elle est bien plus merdique parce que logiciellement, on ne peut pas y faire grand chose. Donc on ne peut pas corriger la faille en question sans revoir les architectures processeur en question.
De ce que j’ai compris, il y a plusieurs moyen de faire l’exploit, le papier en présente deux. Dans tous les cas c’est basé sur le fait d’exécuter spéculativement du code qui n’aurait pas dû être exécuté et l’utilisation d’un side-channel. Pour s’assurer qu’on va exécuter le mauvais code, on va commencer par entraîner le prédicteur de branche pour qu’il fasse le choix dont on a envie en tant qu’attaquant.
La première attaque fait ça pour une branche conditionnelle. On force le processeur à faire deux accès pourris, le premier qui va être celui qui contrôle la valeur de branche (et qui va entraîner la fausse prédiction) et le second qui fait l’accès "secret". Le temps qu’on s’aperçoive que le choix était pourri, le second accès va impacter le cache de telle manière qu’en l’observant ensuite, on puisse déduire quelle donnée était secrète.
La seconde fait ça pour un saut arbitraire. L’idée est d’entraîner le programme victime à sauter à un endroit qui va permettre de faire fuiter de l’information par l’utilisation d’un emplacement mémoire sur lequel l’attaquant à du contrôle. On donne cette valeur à une opération qui manipule des données secrètes et en sautant à l’opération qui manipule à la fois les données secrètes et la valeur de contrôle, on peut arriver à tirer les informations secrètes progressivement.
Cependant, je ne comprends pas encore tout du papier. En particulier, je ne comprends pas le degré de contrôle dont on a besoin l’attaquant, ni les contraintes qu’il doit respecter pour réussir l’attaque. Si quelqu’un a compris, une explication serait pas de refus.
En tout cas, il est intéressant de voir que finalement, cette seconde "faille" correspond en fait à un comportement voulu du processeur qui a été intelligemment détourné. Elle semble très difficile à exploiter mais le gain pour l’attaquant est énorme. Et dans le cas des clouds providers, on a presque l’impression que l’hyperviseur ne peut rien faire si la VM est configurée pour réaliser l’attaque, c’est assez impressionnant.
Finalement, à vouloir trop accélérer nos processeur sur single-thread, on a fini par se brûler les ailes.
De mon côté je potasse la première, et le problème vient à mon sens d’ici :
this hardware-based isolation through a permission
bit is considered secure and recommended by the
hardware vendors. Hence, modern operating systems always
map the entire kernel into the virtual address space
of every user process.
As a consequence, all kernel addresses lead to a valid
physical address when translating them, and the CPU can
access the content of such addresses.
Je ne savais pas que les adresses noyau étaient considérées valides par défaut. Comme tu l’as dit, Ksass`Peuk, ils ont peut-être voulu accélérer les choses en évitant de se taper des interruptions de type Page Fault si un programme (utilisateur uniquement ?) venait à accéder directement à une adresse résidant dans l’espace noyau. Car une interruption, c’est coûteux. Ici, il est question de vérifier le niveau de l’anneau de protection et ainsi interdire l’accès au programme ("Segmentation Fault") ou non.
Je continue ma lecture (mais je commence à avoir la caboche qui surchauffe, moi qui adore pourtant ce genre de sujet…).
Cela me fait penser à la discussion sur ce topic. Le patch KPTI induit des problèmes de performances pour éviter de se faire avoir par Meltdown. Je me demande si un noyau à micro-services aurait évité ce genre de mésaventure dès le début puisqu’on est supposé éviter,je pense la lecture "à tout va" de l’espace mémoire du noyau.
L’auteur des schémas sur cette page n’est sûrement pas inconnu de certains ici. Dommage qu’il ne soit pas ici pour discuter de tout cela avec nous, ça nous aurait sûrement aidés.
Cela dit, j’ai VRAIMENT hâte que @lthms nous dise ce qu’il pense de tout ça…
Vu comment AMD chute, ça va leur faire du bien et donc faire du bien à tout le marché. Parce que une entreprise avec un trop gros monopole, c’est pas cool.
Je ne savais pas que les adresses noyau étaient considérées valides par défaut. Comme tu l’as dit, Ksass`Peuk, ils ont peut-être voulu accélérer les choses en évitant de se taper des interruptions de type Page Fault si un programme (utilisateur uniquement ?) venait à accéder directement à une adresse résidant dans l’espace noyau. Car une interruption, c’est coûteux. Ici, il est question de vérifier le niveau de l’anneau de protection et ainsi interdire l’accès au programme ("Segmentation Fault") ou non.
J’ai pas encore lu les whitepapers pour comprendre les attaques, donc je ne peux pas en discuter dans les détails pour l’instant, par contre, pour cette question, sur ARM, on se ballade en général avec 2 translation tables, une qui contient le mapping mémoire du kernel, et une qu’on change à chaque changement de process userland. Il faut que le processeur sache où est physiquement placé le kernel dans la mémoire pour faire un appel système, donc même quand on est dans le userland, le processeur sais à quelle adresse physique trouver la translation table du kernel. Par contre, toute la mémoire mappée pour le kernel est marquée comme non accessible depuis un niveau d’execution non-privilégié (le userland).
Pour les failles, l’explication de principe de ARM, c’est qu’un branchement prédictif peut récupérer une valeur à laquelle on ne devrait pas avoir accès, et le programme n’y aura effectivement jamais accès, mais si cette valeur est utilisée pour effectuer un autre branchement, en fonction du temps d’accès, on peut déduire à quelle mémoire on a accédé (par exemple en récupérant un bit d’information à laquelle on ne devrait pas avoir accès, on peut faire un branchement vers une page parmi deux auxquelles on a le droit d’accéder, et déduire la valeur du bit à partir du temps d’accès mémoire à chacune de ces pages par la suite). La difficulté est de trouver une routine qui va faire un accès mémoire qu’on va savoir reconnaître et discriminer. A priori, ils ont exploité eBPF pour ça, mais n’importe quelle interprétation de bytecode par le kernel peut être exploitée. Sinon, il faut connaître le kernel à l’avance pour trouver une routine qui fait déjà ce qu’on veut, c’est moins pratique. Y’a d’autres variantes, mais l’idée va toujours être d’observer les résultats des chargements prédictifs de pages de cache ou les comportement des unités de prédictions préalablement entrainées avec les données à faire leaker pour réussir à gratter quelques informations venant d’une mémoire à laquelle on n’a pas accès.
Pour faire leaker du contenu du Trusted Execution Environment (TrustZone), c’est pas forcément aussi simple. Dans l’implémentation que j’ai au bureau, le code TrustZone s’execute directement à son adresse physique, sans MMU, il n’est mappé nul part, et, dans ce mode, il n’y a pas d’execution out of order possible sur ARM, ni même de mise en cache, vu que la mémoire est considérée comme device (un type de mémoire dans le vocabulaire ARM). Pour des implémentations qui utilisent un peu mieux le proc (comme l’implémentation de référence de ARM pour ARMv8A), faire débuter tous les appels au monde secure par une éviction de tout le cache permet d’empêcher de donner accès à des routines dont le temps d’execution indique le résultat (mais ça a une coup en performance). Les patches actuels utilisent à peu près la même méthode pour protéger la mémoire de l’hyperviseur.
[…] Le patch KPTI induit des problèmes de performances pour éviter de se faire avoir par Meltdown. Je me demande si un noyau à micro-services aurait évité ce genre de mésaventure dès le début puisqu’on est supposé éviter,je pense la lecture "à tout va" de l’espace mémoire du noyau.
Je pense que ça n’aurait pu changer quelque chose que si (refaire le monde, tout ça) l’architecture en micro-noyau (et même pas micro-noyau hybride comme dans Windows) s’était complètement imposée il y a déjà un certain temps. Auquel cas, on aurait peut-être pas introduit le KASLR. (Et pour Spectre rien n’aurait changé a priori).
Le soucis ici est vraiment que les adresses kernel sont conservés dans un cache particulier pour ne pas avoir à les recharger. Donc même si tu passes sur des micro-services, il n’y a pas de raison que l’on flush plus souvent le cache système : on ne le flush pas de toute façon.
J’ai contacté un pote qui fait la sécu pour avoir un coup de main pour comprendre la mise en oeuvre pour Spectre. Normalement cet article est plus digeste que les white-papers :
Connectez-vous pour pouvoir poster un message.
Connexion
Pas encore membre ?
Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte