2 points par GN⁺ 2023-07-25 | 1 commentaires | Partager sur WhatsApp
  • Zenbleed est une vulnérabilité qui exploite la restauration incorrecte d’un vzeroupper mal prédit sur les processeurs AMD Zen 2, permettant de lire les données restantes dans le fichier de registres vectoriels du même cœur physique
  • Elle est répertoriée sous CVE-2023-20593 et affecte la famille Zen 2, notamment Ryzen 3000/4000/5000 with Radeon Graphics/7020 with Radeon Graphics, Ryzen PRO, Threadripper 3000, EPYC « Rome »
  • L’attaque fonctionne lorsque XMM Register Merge Optimization, le renommage de registres et un vzeroupper mal prédit s’enchaînent dans une fenêtre temporelle étroite ; des opérations de base comme strlen, memcpy et strcmp peuvent également être observées
  • Une variante optimisée peut exfiltrer environ 30 Ko par seconde et par cœur ; le partage du fichier de registres sur un même cœur physique pose problème au-delà des frontières entre VM, sandbox, conteneurs et processus
  • Il est recommandé d’appliquer la mise à jour du microcode AMD ; temporairement, il est possible de définir le chicken bit DE_CFG[9], mais cela peut avoir un coût en performances et désactiver SMT ne suffit pas à lui seul

Les unités d’exécution ciblées par Zenbleed

  • Les CPU x86-64 disposent de registres vectoriels XMM de 128 bits, que les CPU modernes étendent jusqu’aux YMM de 256 bits et aux ZMM de 512 bits
  • Les registres vectoriels sont utilisés non seulement pour le calcul numérique, mais aussi dans les fonctions de la bibliothèque C standard de glibc comme strcmp, memcpy et strlen
  • L’implémentation strlen optimisée AVX2 de glibc combine plusieurs instructions vectorielles pour trouver la position du premier octet nul dans une chaîne
    • vpxor xmm0,xmm0,xmm0 met à zéro la partie basse de ymm0
    • vpcmpeqb ymm1,ymm0,[rdi] compare les octets de la chaîne avec des octets à zéro
    • vpmovmskb eax,ymm1 transfère le résultat de la comparaison dans un registre général
    • tzcnt eax,eax calcule la position du premier octet nul

vzeroupper et le fichier de registres

  • vzeroupper est une instruction qui met à zéro les bits hauts des registres vectoriels
  • Lorsque des registres XMM et YMM sont utilisés conjointement, un registre XMM est promu à la largeur complète, ce qui peut créer une dépendance aux bits hauts
  • glibc utilise vzeroupper pour éviter des stalls inutiles et faire en sorte que les résultats ultérieurs ne dépendent pas des bits hauts
  • Le CPU ne place pas chaque registre à un emplacement physique fixe : il gère l’allocation des registres physiques via le Register File et la Register Allocation Table
  • Lorsqu’un registre XMM est mis à zéro, le CPU peut ne pas stocker les bits réels et se contenter de définir un drapeau z-bit dans la RAT
    • Ce drapeau peut être appliqué indépendamment aux parties haute et basse d’un registre YMM
    • vzeroupper peut définir le z-bit puis libérer la ressource correspondante dans le fichier de registres

La vulnérabilité créée lors de la restauration de l’exécution spéculative

  • Les CPU modernes utilisent l’exécution spéculative : les opérations exécutées sur une branche mal prédite doivent donc être annulées
  • Le problème est qu’après l’exécution d’un vzeroupper mal prédit, lors de la restauration, annuler seulement le z-bit ne permet pas de restaurer correctement l’état des ressources du fichier de registres déjà libérées
  • Avec un ordonnancement précis, il est possible de faire en sorte que certains processeurs se restaurent incorrectement après un vzeroupper mal prédit
  • Cette technique correspond à CVE-2023-20593 et affecte toute la famille Zen 2
    • AMD Ryzen 3000 Series Processors
    • AMD Ryzen PRO 3000 Series Processors
    • AMD Ryzen Threadripper 3000 Series Processors
    • AMD Ryzen 4000 Series Processors with Radeon Graphics
    • AMD Ryzen PRO 4000 Series Processors
    • AMD Ryzen 5000 Series Processors with Radeon Graphics
    • AMD Ryzen 7020 Series Processors with Radeon Graphics
    • AMD EPYC “Rome” Processors

Conditions d’attaque et périmètre des fuites

  • Pour déclencher le bug, XMM Register Merge Optimization, le renommage de registres et un vzeroupper mal prédit doivent s’enchaîner dans une fenêtre temporelle précise
  • Une séquence d’instructions d’exemple utilise la structure suivante
    • vcvtsi2s{s,d} déclenche la merge optimization
    • vmovdqa déclenche le renommage de registres
    • Si une branche conditionnelle est taken mais que le CPU prédit le chemin not-taken, vzeroupper est exécuté à tort de manière spéculative et le bug se produit
  • Comme des opérations de base telles que strlen, memcpy et strcmp utilisent les registres vectoriels, elles peuvent être observées où qu’elles s’exécutent sur le système
  • Comme le fichier de registres est partagé sur un même cœur physique, d’autres VM, sandbox, conteneurs et processus entrent également dans le périmètre d’impact
  • Deux hyperthreads partagent le même fichier de registres physiques
  • Une variante optimisée de l’attaque peut exfiltrer environ 30 Ko par seconde et par cœur, un débit suffisant pour surveiller les clés de chiffrement et les mots de passe d’un utilisateur connecté
  • L’avis technique et le code associé sont publiés dans le security research repository de Google
  • Le code de test est fourni pour Linux, mais le bug ne dépend pas d’un système d’exploitation particulier : tous les systèmes d’exploitation sont affectés

Méthode de découverte : fuzzing CPU et Oracle Serialization

  • La vulnérabilité a été découverte par fuzzing
  • L’industrie des CPU réalise elle aussi une validation après fabrication du silicium (Post-Silicon Validation) afin de trouver des défauts matériels
  • Contrairement au fuzzing classique fondé sur la couverture, les CPU n’ont pas de métrique correspondant directement à la couverture de code
  • À la place, des performance counters sont utilisés pour fournir au fuzzer un retour sur des événements architecturaux intéressants
    • Cette méthode permet d’explorer des séquences d’instructions difficiles à découvrir par hasard
    • Elle a permis de découvrir automatiquement des fonctionnalités comme la merge optimization
  • Le fuzzing logiciel recherche généralement des crashs, mais dans des programmes CPU générés aléatoirement, un crash peut lui-même être un comportement correct
  • Une approche existante, reversi, génère l’opération inverse de chaque instruction aléatoire et vérifie si l’état final diffère de l’état initial
    • Sur une architecture CISC comme x86, la génération de cas de test devient complexe
  • Une autre méthode consiste à utiliser un oracle pour comparer les résultats du CPU testé avec ceux d’un autre CPU ou d’un simulateur
  • Oracle Serialization combine ces deux idées
    • Un programme aléatoire est généré, puis automatiquement transformé sous une forme sérialisée
    • Des éléments de sérialisation comme store/load barrier, speculation fence et cache line flush sont ajoutés
    • Le programme original et le programme sérialisé doivent produire la même sortie, même si leurs caractéristiques de performance diffèrent
  • Si les états finaux ne correspondent pas, il peut s’agir d’une erreur d’exécution microarchitecturale, et cette divergence a mené à la découverte de Zenbleed

Correctifs et limites de la détection

  • La vulnérabilité a été signalée à AMD le 15 mai 2023
  • AMD a publié une mise à jour du microcode pour les processeurs affectés
  • Les fournisseurs de BIOS ou de systèmes d’exploitation peuvent déjà proposer des correctifs incluant cette mise à jour
  • La mesure recommandée est d’appliquer la mise à jour du microcode
  • Lorsqu’il n’est pas possible d’appliquer la mise à jour, il est possible, comme contournement logiciel, de définir le chicken bit DE_CFG[9]
    • Cela peut avoir un coût en performances
    • Sous Linux, il est possible de le définir sur tous les cœurs avec msr-tools
    • Sous FreeBSD, il faut utiliser cpucontrol(8)
    • Pour les autres systèmes d’exploitation, si vous ne savez pas comment configurer les MSR, une assistance du fournisseur est nécessaire
  • Désactiver SMT ne suffit pas
  • Aucune technique fiable de détection d’attaque n’est connue
    • Parce qu’aucun appel système ni privilège particulier n’est nécessaire
    • Il n’est pas non plus possible de détecter statiquement un usage inapproprié de vzeroupper

1 commentaires

 
GN⁺ 2023-07-25
Avis de Hacker News
  • C’est vraiment impressionnant, et cela pourrait devenir un cas d’école montrant qu’exécuter quelque chose dans une VM ne le rend pas sûr pour autant
    Les évasions de VM ont toujours été connues, mais ici il s’agit d’une vulnérabilité à grande échelle, simple à exploiter et très rentable, même sans évasion
    Le fait que ce bug soit corrigé par du microcode ne signifie pas qu’il n’existe pas d’autres bugs similaires. Beaucoup de 0-day sont souvent connus des mercenaires black hats bien avant d’être rendus publics
    Vulnérabilités CPU découvertes ces dernières années :
    https://en.wikipedia.org/wiki/Meltdown_(security_vulnerability)
    https://en.wikipedia.org/wiki/Spectre_(security_vulnerability)
    https://aepicleak.com/
    https://en.wikipedia.org/wiki/Software_Guard_Extensions#SGAxe
    https://en.wikipedia.org/wiki/Software_Guard_Extensions#LVI
    https://en.wikipedia.org/wiki/Software_Guard_Extensions#Plundervolt
    https://en.wikipedia.org/wiki/Software_Guard_Extensions/…
    https://en.wikipedia.org/wiki/Software_Guard_Extensions#Enclave_attack
    https://en.wikipedia.org/wiki/Software_Guard_Extensions/…
    https://www.vusec.net/projects/crosstalk/
    https://en.wikipedia.org/wiki/Hertzbleed
    https://securityweek.com/amd-processors-expose-sensitive-data-new-squi…

    • Le problème, c’est qu’une VM n’est plus vraiment une machine virtuelle
      Elle n’interprète pas les instructions via un grand switch ; elle les exécute sur le CPU réel et s’appuie sur quelques flags matériels par lesquels le CPU garantit que les données ou les instructions ne se chevauchent pas. Le CPU le promet, mais dans la réalité il est difficile de tenir ce genre de promesse
    • La comparaison avec Meltdown/Spectre peut être un peu trompeuse
      Dans leur cas, le CPU faisait exactement ce qu’il était censé faire, mais cela a rendu possible une forme d’attaque entièrement nouvelle basée sur le timing ; Zenbleed ressemble davantage à un bug traditionnel où des données qui ne devraient pas s’y trouver restent dans des registres
    • Exécuter du code non fiable dans une sandbox, un conteneur ou une VM n’est plus sûr, au moins depuis Rowhammer
      Je pense que beaucoup de ces vulnérabilités viennent du fait que le logiciel et le matériel ne se parlent pas correctement. Côté logiciel, on fait des hypothèses sur les garanties d’isolation ; côté matériel, on ne signale pas assez clairement quand de telles hypothèses risquent d’apparaître
    • Au final, j’ai l’impression que la plupart de ces problèmes sont liés à la prédiction de branchement
      La prédiction de branchement semble soit intrinsèquement trop complexe, au point d’être toujours exposée à ce type de vulnérabilité, soit trop éloignée de notre manière intuitive de comprendre les chemins de code et l’exécution des instructions, ce qui rend difficile d’imaginer les cas limites avant qu’il ne soit trop tard
      La complexité des architectures CPU finira-t-elle, à partir d’un certain point, par devenir trop difficile à raisonner, au point que nous accepterons la perte de performance liée au fait de les garder plus simples ?
    • J’ai vu certaines entreprises mélanger des VM exposées à Internet/en DMZ et des VM internes sur le même hyperviseur
      Je l’ai signalé et recommandé de les isoler physiquement sur des hyperviseurs séparés, mais on m’a toujours ignoré. Au final, ce sera sans doute leur problème
  • Le README du fichier tar de l’exploit contient davantage de détails ainsi que le calendrier de divulgation
    2023-05-09 Un composant du pipeline de validation CPU produit un résultat anormal
    2023-05-12 Le problème est isolé et reproduit avec succès, l’enquête se poursuit
    2023-05-14 La portée et la gravité du problème sont déterminées
    2023-05-15 Rédaction d’un bref rapport d’état et partage avec l’AMD PSIRT
    2023-05-17 AMD confirme la réception du rapport et reconnaît que le problème est reproductible
    2023-05-17 Développement d’un PoC fiable terminé et partagé avec AMD
    2023-05-19 Début de la notification aux principaux fournisseurs de noyaux et d’hyperviseurs
    2023-05-23 Réception d’une mise à jour de microcode bêta pour Rome de la part d’AMD
    2023-05-24 Confirmation que la mise à jour corrige le problème et information transmise à AMD
    2023-05-30 AMD indique avoir envoyé un avis de sécurité à ses partenaires
    2023-06-12 Réunion avec AMD pour discuter de l’état et des détails
    2023-07-20 AMD publie le correctif sans préavis, avant la date d’embargo convenue
    2023-07-21 Puisque le correctif est public, proposition d’informer en privé les principales distributions afin qu’elles préparent des mises à jour de leurs paquets de firmware
    2023-07-24 divulgation publique

  • C’est vraiment effrayant. Sur ma machine Zen 2, un Ryzen 3600, j’ai exécuté l’exploit avec un utilisateur non privilégié, puis copié-collé une chaîne dans un éditeur de texte en arrière-plan (Kate) : en quelques secondes, des fragments de cette chaîne étaient enregistrés dans la sortie de zenbleed
    Heureusement, cet exploit dépend fortement d’une routine assembleur précise, donc il semble très difficile à exploiter depuis le JS ou le WASM d’un navigateur. Sinon, il suffirait sans doute de laisser un onglet malveillant ouvert en arrière-plan pendant quelques heures pour provoquer facilement une fuite
    J’attends que les mainteneurs Fedora publient le nouveau microcode afin que le noyau puisse le charger au démarrage

    • Au moins une personne ici dit pouvoir le reproduire aussi en JavaScript : https://news.ycombinator.com/item?id=36849767
    • J’ai aussi essayé sur ma machine Zen 2, et la même attaque fonctionne même exécutée dans KVM
    • Une fois qu’une méthode sera trouvée en JS, elle semble susceptible de s’appliquer assez largement
      En même temps, j’espère que des correctifs logiciels dans V8 et SpiderMonkey arriveront plus tôt et apporteront une atténuation supplémentaire
      Cela dit, un exploit JS aurait aussi besoin d’une méthode pour exfiltrer les données, et il me semble assez difficile de la dissimuler complètement
    • Je ne sais pas comment compiler le PoC. Sur Ubuntu, j’obtiens "No such file or directory" et une erreur 127
  • Le fait qu’OpenBSD ait ajouté le chargement du microcode AMD au cours des trois derniers jours ne ressemble pas à une coïncidence
    https://news.ycombinator.com/item?id=36838511

  • La formulation selon laquelle AMD aurait publié une mise à jour du microcode pour les processeurs affectés ne me semble pas exacte
    AMD a publié une mise à jour du microcode[0] pour les modèles family 17h 0x31 et 0xa0, ce qui correspond, d’après WikiChip[1], à Rome, Castle Peak et Mendocino
    Jusqu’à présent, il ne semble pas y avoir de mise à jour du microcode pour Renoir, Grey Hawk, Lucienne, Matisse ni Van Gogh. Heureusement, le nouveau kernel peut simplement définir le chicken bit pour ceux-ci, et c’est effectivement ce qu’il fait[2]
    [0] https://git.kernel.org/pub/scm/linux/kernel/git/firmware/lin...
    [1] https://en.wikichip.org/wiki/amd/cpuid#Family_23_.2817h.29
    [2] https://github.com/torvalds/linux/commit/522b1d69219d8f08317...

  • En regardant la partie concernée, cette technique correspond à CVE-2023-20593, fonctionne sur tous les processeurs de classe Zen 2 et inclut au moins les produits suivants
    AMD Ryzen 3000 Series Processors
    AMD Ryzen PRO 3000 Series Processors
    AMD Ryzen Threadripper 3000 Series Processors
    AMD Ryzen 4000 Series Processors with Radeon Graphics
    AMD Ryzen PRO 4000 Series Processors
    AMD Ryzen 5000 Series Processors with Radeon Graphics
    AMD Ryzen 7020 Series Processors with Radeon Graphics
    AMD EPYC “Rome” Processors

    • Je me demande si cela veut dire « confirmé uniquement sur Zen 2 », ou si le problème est réellement limité à cette architecture
      Est-il possible que la même technique, ou une technique similaire, fonctionne aussi sur des cœurs Zen/Zen+ plus anciens ou Zen 3 plus récents, sans que cela ait encore été démontré ?
    • Mon 2700X semble y avoir échappé de justesse. À condition que la série 7020 soit affectée et pas la série 7000
    • Je me demande ce qu’il en est de la PlayStation 5. Même question pour la Xbox et l’appareil de Valve
    • Les Ryzen 5000 sans Radeon ne sont donc pas vulnérables ? Ces processeurs semblent être en Zen 3
      Mon AMD Ryzen 9 5950x Desktop Processor a lui aussi l’air d’être en Zen 3, donc ça devrait aller
      Je n’exécute pas de workloads non fiables, mais comme on dit, la chance sourit aux gens préparés
    • À noter que les APU Ryzen 3000 ne sont pas du Zen 2
  • Le site est en train de mourir sous le trafic : https://web.archive.org/web/20230724143835/https://lock.cmpx...

    • C’est une simple page HTML statique, et je ne vois pas comment un site statique peut tomber sous le trafic en 2023
      Dans la plupart des cas, le trafic de HN atteint à peine 100 pages vues par seconde
    • Lien plus rapide : https://archive.is/QAwvQ
    • L’original finit quand même par se charger. Ça peut dépendre de l’environnement
  • https://www.amd.com/en/resources/product-security/bulletin/a...
    D’après le bulletin de sécurité d’AMD, les mises à jour de firmware pour les CPU non EPYC ne sortiront pas avant la fin de l’année. D’ici là, les utilisateurs doivent-ils désactiver le chicken bit et accepter la perte de performances ?

    • AMD a perdu la tête ? Ce n’est pas une gravité moyenne
  • Aussi impressionnant qu’effrayant. J’ai fait tourner un échantillon de 10 Mo pendant 1 minute, et j’ai pu « divulguer » une partie de mon mot de passe Bitwarden, mon mot de passe de connexion ssh et des fragments d’identifiants bancaires, qui étaient faciles à reconstituer

  • L’article était vraiment excellent. J’ai particulièrement aimé la partie qui explique comment déterminer si un programme généré aléatoirement s’est exécuté correctement.
    L’approche évidente consiste à l’exécuter sur un oracle, comme un autre processeur ou un simulateur, pour vérifier qu’il se comporte de la même manière.
    Mais pour observer des effets microarchitecturaux dans une fenêtre temporelle étroite, on peut aussi écrire le même programme en y insérant divers stall, fence, nop, etc. Dans du code monothread, cela ne devrait pas affecter la sortie, mais en interne, le CPU finit par faire des choses assez différentes au niveau microarchitectural. Ainsi, le CPU peut devenir son propre oracle.

    • J’ai trouvé cette partie vraiment intéressante, en particulier la différence entre le fuzzing logiciel et le fuzzing matériel.
      J’ai aussi bien aimé le chicken bit.