Re: Meltdown - VMs sicher nach Hypervisor-patch?
Oliver Fromme <[email protected]> Wed, 10 Jan 2018 14:11:50 +0100 (CET)
| Newsgroups | gmane.os.freebsd.questions.german |
|---|---|
| Message-ID | <[email protected]> |
Hallo Peter, Peter Ross wrote: > Ganz grob gedacht und gefragt: Wenn der Hypervisor in Sachen Hardware (und > sicher auch CPU-Caching) das letzte Wort hat, kann Meltdown noch innerhalb > der VM ausgenutzt werden? Meltdown nicht – aber Spectre. Grob gesagt: Der Meltdown-Bug (CVE-2017-5754) erlaubt es einem Angreifer, die Trennung zwischen den Ringen [1] zu überwinden. So kann ein normaler Benutzerprozess (Ring 3) auf den Adressraum des Kernels oder des Hypervisors zugreifen. Vom Meltdown-Bug sind alle (neueren) Intel-CPUs betroffen sowie einige (wenige) ARM-Versionen, nicht aber AMD oder andere. Der Bug lässt sich durch Work-arounds im Betriebssystem fixen, die aber einen gewissen Performanceverlust bedeuten. Außerdem hat Intel angekündigt, Microcode-Updates für betroffene Prozessoren herauszubringen, die im Zusammenspiel mit (weiteren) Betriebssystem-Patches den Performanceverlust wieder ausgleichen sollen. [1] https://de.wikipedia.org/wiki/Ring_%28CPU%29/x86-Prozessor-Systeme Das Spectre-Problem dagegen erlaubt das Überwinden von Zugriffs- beschränkungen des eigenen Adressraums (Variante 1, CVE-2017-5753) und der Trennung des Adressraums zwischen verschiedenen Prozessen oder VMs (Variante 2, CVE-2017-5715). Das bedeutet, dass ein Angreifer den Speicher „benachbarter“ Prozesse bzw. VMs auslesen kann. Spectre missbraucht ein grundlegendes Problem bestimmter Prozessor-Optimierungen (Out-of-order Execution und Speculative Execution), daher betrifft es alle Prozessoren, die diese Features besitzen: Intel, AMD, ARM, MIPS, Sparc, ... Dieses Problem zu beheben, ist daher auch um einiges schwieriger. Für Variante 2 gibt es zumindest inzwischen einen vorläufigen Patch für den Compiler LLVM: http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20180101/513630.html Den aktuellen Stand bei FreeBSD findet man hier: https://lists.freebsd.org/pipermail/freebsd-security/2018-January/009719.html Falls es jemanden interessiert, wie so ein Spectre-Angriff in einem Programm grundsätzlich funktioniert: 1. Der Angreifer liest ein Byte an einer bestimmten Adresse aus, zu der er eigentlich keine Zugriffsberechtigung hat. Der Zugriff wird daher fehlschlagen, d.h. zu einem Memory-Fault führen. 2. Da ein Speicherzugriff immer etwas länger dauert, wartet der Prozessor das Ergebnis nicht ab, sondern führt bereits die nachfolgenden Anweisungen „spekulativ“ aus, bevor der Memory- Fault ausgelöst wird. 3. Die folgende Anweisung maskiert ein Bit des (vermeintlich) gelesenen Bytes heraus und greift in Abhängigkeit davon auf zwei verschiedene Adressen (nennen wir sie A0 und A1) zu, d.h. wenn das Bit 0 ist, wird auf A0 zugegriffen, und wenn es 1 ist, wird auf A1 zugegriffen. Wo A0 und A1 liegen, spielt keine Rolle, sie sollten nur in unterschiedlichen Cache-Lines liegen. Ihr Inhalt ist auch egal und interessiert nicht. 4. Der Memory-Fault, der nun irgendwann zuschlägt, führt dazu, dass der Prozessor das Byte aus Schritt 1. natürlich nicht herausrückt, und die spekulativ ausgeführten Schritte (3.), die auf dem Inhalt dieses Bytes basieren, werden auch wieder verworfen. 5. Das Programm muss natürlich dafür sorgen, dass es trotzdem weiterläuft, z.B. durch einen Trap-Handler (SIGSEGV), oder es lässt den Thread/Prozess einfach sterben und setzt den Ablauf in einem Schwester-Prozess fort. 6. Obwohl der Prozessor die spekulativen Schritte verworfen hat, haben sie einen Seiteneffekt: Der Inhalt von A0 *oder* A1 wurde in den Cache geholt und befindet sich noch dort. 7. Das Programm muss jetzt also nur einen kleinen Timing-Test machen, indem es misst, wie lange ein Zugriff auf A0 und A1 dauert. Je nachdem, welches der beiden schneller ist, weiß das Programm, welche Adresse bereits vorher in den Cache geladen wurde, und somit, welchen Wert das fragliche Bit hatte. 8. Obige Schritte können beliebig oft wiederholt werden, um die Bits (und somit Bytes) zu erhalten, die einen interessieren, und auf die man eigentlich keine Zugriffsberechtigung hat. Das klingt jetzt nach eine Riesenaufwand für jedes einzelne Bit, aber in der Praxis (mit dem PoC-Code) kann man auf einer halbwegs schnellen CPU mehrere hundert KByte/s lesen, was für typische Angriffsszenarien völlig ausreichend ist. Gruß Olli -- Oliver Fromme, München -- FreeBSD + DragonFly BSD ``We are all but compressed light'' - Albert Einstein To Unsubscribe: send mail to [email protected] with "unsubscribe de-bsd-questions" in the body of the message