« Lettre ouverte au(x) cuistre(s) qui nous gouvernent | N'est pas JFK qui veut » |
La presse vient d'annoncer la découverte de deux failles dans les processeurs de type x86 (principalement Intel et ARM Cortex-A même si d'autres AMD et Power semblent aussi concernés). Il s'agit des exploits Spectre et Meltdown.
Il faut noter que les processeurs les plus touchés, les x86 d'Intel et les ARM Cortex-A n'ont a priori rien à voir entre eux. Par ailleurs, les ARM Cortex-A sont fabriqués par des fondeurs différents et il n'y a là aussi aucune raison que des processeurs sortis de deux usines de fondeurs différents soient affectés par hasard des mêmes dysfonctionnements.
Il y a quinze ans, j'avais écrit un papier sur l'évolution des processeurs qui concluait sur la nécessaire production de ce genre de faille en tant qu'effet de bord de l'évolution forcenée. En effet, les fondeurs se sont livré des batailles sur le front des consommations électriques et des fréquences tout en gardant les erreurs de jeunesse de leurs processeurs pour raisons de compatibilité.
Ainsi, les processeurs ARM et x86 possèdent des ABI étranges pour ne pas dire totalement moisies. Non seulement, elles embarquent des bugs de compatibilité (ah, le bug de la ligne A20 du 8086 ! Qu'est-ce qu'il nous aura ennuyé, celui-là !), mais pour des raisons tout aussi historiques, les instructions n'ont pas de format fixe. Ces instructions de format variable sont issues des différentes générations des processeurs CISC. Or un processeur CISC n'aime pas monter en fréquence. Pensez donc au processeur VAX qui comprenait je ne sais plus combien de formats de flottants et embarquait même un type de liste chaînée ! Il est illusoire de prétendre réussir à traiter toutes les instructions de manipulation de ces données en un nombre identique de cycles d'horloge, ce qui revient à dire que les pipelines sont très compliqués à rendre efficaces, les instructions courtes ayant tendance à les vider. D'autre part, les branchements et sauts qui sont efficacement traités par un processeur RISC — traitement des deux branches en parallèle et élagage de celle qui ne doit pas être exécutée, ce qui est rendu possible par une nombre fixe de cycles par instruction — se traduit par des contorsions de la logique et des suppositions du processeurs quant à la branche qui aura le plus de chance d'être la branche à exécuter.
Les x86 et les ARM sont devenus de vrais maîtres en la matière. Non seulement les instructions sont de formats variables (pour des raisons différentes, historiques pour les x86 et d'occupation mémoire pour l'ARM), mais ils doivent aussi fonctionner à de hautes fréquences en consommant le moins possible. Et si possible en ayant des instructions s'exécutant en un nombre de cycles pas trop différents de l'une à l'autre pour ne pas pénaliser les pipelines.
Ces contraintes aboutissent à l'utilisation de prédiction de sauts, d'exécution out of order et à une logique interne délirante si on veut la définir entièrement. Or un automate entièrement défini est très complexe et le nombre de cellules en cascade interdit souvent une montée en fréquence, ce qui fut le problème majeur lors de la conception des processeurs Alpha. Typiquement, l'ajout d'une simple condition de test peut réduire la vitesse de fonctionnement d'un facteur non négligeable en raison des simples délais de propagation entre portes logiques. La question que se sont posés les fondeurs est donc de savoir s'il était intéressant d'utiliser une machine entièrement définie ou s'il n'était pas plus légitime d'utiliser des états indéterminés sachant que ces états, en fonctionnement normal, ne seraient jamais atteints. Plus exactement en espérant que ces états ne seront jamais atteints. Or nous en sommes là, il est possible d'atteindre certains de ces états, ce qui conduit les processeurs à des états étranges et à des perméabilités entre espaces mémoires qui ne devraient jamais se voir.
Ce ne serait que risible si l'écosystème informatique entier n'était pas atteint de dégénérescence. En effet, il y a encore quelques années, il existait plusieurs architectures concurrentes. Je ne citerai que les Sparc/Sparc64, Power, PowerPC, MIPS, ARM, x86, IA64, AXP… Aujourd'hui, l'immense majorité des machines est conçue pour des raisons de coût autour des processeurs x86 (Intel ou AMD, je ne sais pas s'il existe encore d'autres fondeurs de x86) ou ARM appauvrissant d'autant les systèmes. Il reste bien quelques niches pour les Sparc, Power(PC) et MIPS, mais elles sont de plus en plus petites.
Je me souviens qu'il y a quinze ans, tout le monde me disait que les x86 étaient l'avenir parce qu'ils étaient moins chers et fonctionnaient plus vite. Certes, mais à quel prix ? Où en sommes-nous aujourd'hui ? En électronique, il est simplement impossible d'avoir le beurre, l'argent du beurre et le sourire de la crémière. Le croire ne conduit qu'à des catastrophes industrielles. On ne peut pas avoir un processeur aussi complexe qu'un x86/amd64 sans en accepter la face cachée, les coupes sombres dans la logique interne. Je me rappelle aussi qu'on me rétorquait que les Sparc et autres Alpha étaient chers parce que Digital et Sun vendaient trop chers leurs processeurs vis à vis des coûts de conception et de fabrication. Le seul problème, c'est qu'ils en valaient le prix. DEC, avec ses équipes d'ingénieurs de haut vol, sortait un processeur tous les trois ou quatre ans, refusant de le sortir en cas de défaut. Intel sort de nouveaux cœurs tous les six mois à un an. Et on se retrouve avec des bugs à la noix depuis le Pentium et son fumeux bug FDIV.
Mais le monde de l'informatique n'a encore rien compris. Il faudra une catastrophe majeure pour qu'il se rende compte de ses bêtises.
Entre temps, les fondeurs aternatifs, tout au moins ce qui existent encore, ont une carte à jouer.