Abbildung 6: Isolierung der Kernel-SeitentabelleAbbildung 6 zeigt eine Technik namens Kernel Page Table Isolation (KPTI). Dies läuft im Grunde darauf hinaus, den Kernelspeicher nicht in ein Programm abzubilden, wenn es im Benutzerbereich ausgeführt wird. Wenn kein Mapping vorhanden ist, ist eine spekulative Ausführung nicht mehr möglich und wird sofort fehlschlagen.
Zusätzlich dazu, dass der Virtual Memory Manager (VMM) des Betriebssystems komplizierter wird, wird diese Technik ohne Hardwareunterstützung auch Arbeitslasten erheblich verlangsamen, die eine große Anzahl von Übergängen zwischen Benutzermodus und Kernelmodus bewirken, da die Seitentabellen bei jedem Übergang geändert werden müssen und der TLB geleert werden muss (da der TLB möglicherweise veraltete Zuordnungen beibehält).Neuere x86-CPUs verfügen über eine Funktion namens ASID (Address Space ID) oder PCID (Process Context ID), mit der diese Aufgabe erheblich billiger werden kann (ARM und andere Mikroarchitekturen haben diese Funktion seit Jahren). Mit PCID kann eine ID einem TLB-Eintrag zugeordnet werden und dann nur TLB-Einträge mit dieser ID leeren. Die Verwendung von PCID macht KPTI billiger, aber immer noch nicht kostenlos.
Zusammenfassend ist Meltdown eine äußerst schwerwiegende und leicht auszunutzende Sicherheitsanfälligkeit. Glücklicherweise hat es eine relativ einfache Abschwächung, die bereits von allen großen Betriebssystemanbietern bereitgestellt wurde, mit der Einschränkung, dass bestimmte Workloads langsamer laufen, bis zukünftige Hardware explizit für die beschriebene Adressraumtrennung ausgelegt ist.
Spectre vulnerability
Spectre teilt einige Eigenschaften von Meltdown und besteht aus zwei Varianten. Im Gegensatz zu Meltdown ist Spectre wesentlich schwieriger zu nutzen, betrifft jedoch fast alle modernen Prozessoren, die in den letzten zwanzig Jahren hergestellt wurden. Im Wesentlichen handelt es sich bei Spectre um einen Angriff auf das moderne CPU- und Betriebssystemdesign im Vergleich zu einer bestimmten Sicherheitslücke.
Bounds Check Bypass (Spectre Variante 1)
Die erste Spectre Variante wird als „bounds check Bypass“ bezeichnet.“ Dies wird im folgenden Code-Snippet demonstriert (das ist das gleiche Code-Snippet, das ich verwendet habe, um spekulative Ausführung oben einzuführen).
if (x < array1_size) {
y = array2 * 256];
}
Nehmen Sie im vorherigen Beispiel die folgende Abfolge von Ereignissen an:
- Der Angreifer kontrolliert
x
.
-
array1_size
wird nicht zwischengespeichert.
-
array1
wird zwischengespeichert.
- Die CPU vermutet, dass
x
kleiner als array1_size
ist. (CPUs verwenden verschiedene proprietäre Algorithmen und Heuristiken, um zu bestimmen, ob spekuliert werden soll, weshalb die Angriffsdetails für Spectre zwischen Prozessorherstellern und -modellen variieren.)
- Die CPU führt den Hauptteil der if-Anweisung aus, während sie darauf wartet, dass
array1_size
geladen wird, was sich ähnlich wie Meltdown auf den Cache auswirkt.
- Der Angreifer kann dann den tatsächlichen Wert von
array1
über eine von verschiedenen Methoden ermitteln. (Weitere Informationen zu Cache-Inferenzangriffen finden Sie in der Forschungsarbeit.)
Spectre ist erheblich schwieriger auszunutzen als Meltdown, da diese Sicherheitsanfälligkeit nicht von der Eskalation von Berechtigungen abhängt. Der Angreifer muss den Kernel überzeugen, Code auszuführen und falsch zu spekulieren. Normalerweise muss der Angreifer die Spekulationsmaschine vergiften und sie dazu bringen, falsch zu raten. Das heißt, Forscher haben mehrere Proof-of-Concept-Exploits gezeigt.
Ich möchte wiederholen, was für eine wirklich unglaubliche Entdeckung dieser Exploit ist. Ich persönlich halte dies nicht für einen CPU-Designfehler wie Meltdown an sich. Ich halte dies für eine grundlegende Offenbarung darüber, wie moderne Hardware und Software zusammenarbeiten. Die Tatsache, dass CPU-Caches indirekt genutzt werden können, um Zugriffsmuster zu erfahren, ist seit einiger Zeit bekannt. Die Tatsache, dass CPU-Caches als Seitenkanal zum Speichern von Computerspeicher verwendet werden können, ist sowohl konzeptionell als auch in ihren Auswirkungen erstaunlich.
Branch Target Injection (Spectre Variante 2)
Denken Sie daran, dass indirekte Verzweigung in modernen Programmen sehr verbreitet ist. Variante 2 von Spectre verwendet eine indirekte Verzweigungsvorhersage, um die CPU dazu zu bringen, spekulativ an einem Speicherort auszuführen, den sie sonst nie ausgeführt hätte. Wenn die Ausführung dieser Anweisungen einen Zustand im Cache hinterlassen kann, der mithilfe von Cache-Inferenzangriffen erkannt werden kann, kann der Angreifer den gesamten Kernelspeicher sichern. Wie Spectre Variante 1, Spectre Variante 2 ist viel schwieriger zu nutzen als Meltdown, Forscher haben jedoch gezeigt, dass Proof-of-Concept-Exploits von Variante funktionieren 2.
Spectre mitigations
Die Spectre Mitigations sind wesentlich interessanter als die Meltdown Mitigation. Tatsächlich schreibt das akademische Spectre-Papier, dass derzeit keine Milderungen bekannt sind. Es scheint, dass Intel (und wahrscheinlich auch andere CPU-Anbieter) und die großen Betriebssystem- und Cloud-Anbieter hinter den Kulissen und parallel zur akademischen Arbeit seit Monaten wütend daran arbeiten, Abhilfemaßnahmen zu entwickeln. In diesem Abschnitt werde ich die verschiedenen Mitigationen behandeln, die entwickelt und bereitgestellt wurden. Dies ist der Abschnitt, in dem ich am verschwommensten bin, da es unglaublich schwierig ist, genaue Informationen zu erhalten, daher setze ich Dinge aus verschiedenen Quellen zusammen.
Statische Analyse und Fencing (Variante 1 Mitigation)
Die einzige bekannte Variante 1 (Bounds Check Bypass) Mitigation ist die statische Analyse von Code, um Code-Sequenzen zu bestimmen, die vom Angreifer kontrolliert werden könnten, um Spekulationen zu stören. Anfällige Codesequenzen können eine Serialisierungsanweisung wie lfence
eingefügt haben, die die spekulative Ausführung stoppt, bis alle Anweisungen bis zum Zaun ausgeführt wurden. Beim Einfügen von Zaunanweisungen ist Vorsicht geboten, da zu viele schwerwiegende Auswirkungen auf die Leistung haben können.
Retpoline (Variante 2 Mitigation)
Die erste Spectre Variante 2 (Branch Target Injection) Mitigation wurde von Google entwickelt und ist bekannt als „retpoline.“ Es ist mir unklar, ob es isoliert von Google oder von Google in Zusammenarbeit mit Intel entwickelt wurde. Ich würde spekulieren, dass es von Google experimentell entwickelt und dann von Intel-Hardware-Ingenieuren verifiziert wurde, aber ich bin mir nicht sicher. Details zum „retpoline“ -Ansatz finden Sie in Googles Paper zum Thema. Ich werde sie hier zusammenfassen (ich beschönige einige Details, einschließlich des Unterflusses, die in dem Papier behandelt werden).
Retpoline beruht auf der Tatsache, dass das Aufrufen und Zurückgeben von Funktionen und die damit verbundenen Stapelmanipulationen in Computerprogrammen so häufig sind, dass CPUs für ihre Ausführung stark optimiert sind. (Wenn Sie nicht wissen, wie der Stack in Bezug auf das Aufrufen und Zurückgeben von Funktionen funktioniert, ist dieser Beitrag eine gute Einführung.) Kurz gesagt, wenn ein „Anruf“ ausgeführt wird, wird die Rücksprungadresse auf den Stapel geschoben. „ret“ schaltet die Absenderadresse aus und setzt die Ausführung fort. Spekulative Ausführungshardware merkt sich die gepushte Absenderadresse und setzt die Ausführung an diesem Punkt spekulativ fort.
Die retpoline-Konstruktion ersetzt einen indirekten Sprung zu dem im Register r11
gespeicherten Speicherort:
jmp *%r11
mit:
call set_up_target; (1)
capture_spec: (4)
pause;
jmp capture_spec;
set_up_target:
mov %r11, (%rsp); (2)
ret; (3)
Mal sehen, was der vorherige Assemblycode Schritt für Schritt ausführt und wie er die Verzweigungszielinjektion abschwächt.
- In diesem Schritt ruft der Code einen Speicherort auf, der zur Kompilierungszeit bekannt ist, also ein hartcodierter Offset und nicht indirekt ist. Dies platziert die Rücksprungadresse von
capture_spec
auf dem Stapel.
- Die Rücksprungadresse aus dem Aufruf wird mit dem eigentlichen Sprungziel überschrieben.
- Für das reale Ziel wird ein Return ausgeführt.
- Wenn die CPU spekulativ ausgeführt wird, kehrt sie in eine Endlosschleife zurück! Denken Sie daran, dass die CPU spekuliert, bis die Speicherauslastung abgeschlossen ist. In diesem Fall wurde die Spekulation manipuliert, um in einer Endlosschleife erfasst zu werden, die keine für einen Angreifer beobachtbaren Nebenwirkungen aufweist. Wenn die CPU schließlich die reale Rückgabe ausführt, bricht sie die spekulative Ausführung ab, die keine Auswirkung hatte.
Meiner Meinung nach ist dies eine wirklich geniale Lösung. Ein großes Lob an die Ingenieure, die es entwickelt haben. Der Nachteil dieser Abschwächung besteht darin, dass die gesamte Software neu kompiliert werden muss, sodass indirekte Zweige in Retpoline-Zweige konvertiert werden. Für Cloud-Dienste wie Google, die den gesamten Stack besitzen, ist die Neukompilierung keine große Sache. Für andere kann es eine sehr große Sache oder unmöglich sein.
IBRS, STIBP und IBPB (Variante 2 Mitigation)
Es scheint, dass Intel (und AMD bis zu einem gewissen Grad) gleichzeitig mit der Entwicklung von Retpoline an Hardwareänderungen gearbeitet haben, um Branch Target Injection-Angriffe abzuschwächen. Die drei neuen Hardwarefunktionen, die als CPU-Mikrocode-Updates ausgeliefert werden, sind:
- Indirect Branch Restricted Speculation (IBRS)
- Single Thread Indirect Branch Predictors (STIBP)
- Indirect Branch Predictor Barrier (IBPB)
Eingeschränkte Informationen zu den neuen Mikrocode-Funktionen erhalten Sie von Intel hier. Ich konnte grob zusammenstellen, was diese neuen Funktionen tun, indem ich die obige Dokumentation gelesen und mir die Patches für Linux-Kernel und Xen-Hypervisor angesehen habe. Aus meiner Analyse geht hervor, dass jedes Feature möglicherweise wie folgt verwendet wird:
- IBRS leert sowohl den Verzweigungsvorhersagecache zwischen den Berechtigungsstufen (Benutzer zu Kernel) als auch deaktiviert die Verzweigungsvorhersage auf dem Geschwister-CPU-Thread. Denken Sie daran, dass jeder CPU-Kern normalerweise zwei CPU-Threads hat. Es scheint, dass auf modernen CPUs die Verzweigungsvorhersagehardware von den Threads gemeinsam genutzt wird. Dies bedeutet, dass nicht nur Benutzermoduscode den Verzweigungsprädiktor vor der Eingabe von Kernelcode vergiften kann, sondern auch Code, der auf dem Geschwister-CPU-Thread ausgeführt wird, ihn vergiften kann. Das Aktivieren von IBRS im Kernelmodus verhindert im Wesentlichen, dass jede vorherige Ausführung im Benutzermodus und jede Ausführung auf dem Geschwister-CPU-Thread die Verzweigungsvorhersage beeinflusst.
- STIBP scheint eine Teilmenge von IBRS zu sein, die nur die Verzweigungsvorhersage für den Geschwister-CPU-Thread deaktiviert. Soweit ich das beurteilen kann, besteht der Hauptanwendungsfall für diese Funktion darin, zu verhindern, dass ein Geschwister-CPU-Thread den Verzweigungsprädiktor vergiftet, wenn zwei verschiedene Benutzermodusprozesse (oder virtuelle Maschinen) gleichzeitig auf demselben CPU-Kern ausgeführt werden. Es ist mir ehrlich gesagt nicht ganz klar, wann STIBP verwendet werden sollte.
- IBPB scheint den Verzweigungsvorhersagecache für Code zu leeren, der auf derselben Berechtigungsstufe ausgeführt wird. Dies kann verwendet werden, wenn zwischen zwei Benutzermodusprogrammen oder zwei virtuellen Maschinen gewechselt wird, um sicherzustellen, dass der vorherige Code den Code, der gerade ausgeführt wird, nicht beeinträchtigt (obwohl ich ohne STIBP glaube, dass Code, der auf dem Geschwister-CPU-Thread ausgeführt wird, den Verzweigungsprädiktor immer noch vergiften kann).
Zum jetzigen Zeitpunkt scheinen die wichtigsten Mitigationen, die für die Branch Target Injection-Sicherheitsanfälligkeit implementiert werden, sowohl retpoline als auch IBRS zu sein. Vermutlich ist dies der schnellste Weg, um den Kernel vor Benutzermodusprogrammen oder den Hypervisor vor Gästen virtueller Maschinen zu schützen. In Zukunft würde ich erwarten, dass sowohl STIBP als auch IBPB abhängig von der Paranoia verschiedener Benutzermodusprogramme bereitgestellt werden, die sich gegenseitig stören.
Die Kosten für IBRS scheinen auch zwischen den CPU-Architekturen extrem stark zu variieren, wobei neuere Intel Skylake-Prozessoren im Vergleich zu älteren Prozessoren relativ günstig sind. Bei Lyft haben wir eine Verlangsamung bestimmter systemaufrufintensiver Workloads auf AWS C4-Instances um etwa 20% festgestellt, als die Mitigationen eingeführt wurden. Ich würde spekulieren, dass Amazon IBRS und möglicherweise auch Retpoline eingeführt hat, aber ich bin mir nicht sicher. Es scheint, dass Google retpoline möglicherweise nur in seiner Cloud eingeführt hat.
Im Laufe der Zeit würde ich erwarten, dass Prozessoren schließlich zu einem IBRS „always on“ -Modell wechseln, bei dem die Hardware standardmäßig nur die Trennung der Verzweigungsprädiktoren zwischen CPU-Threads bereinigt und den Status bei Änderungen der Berechtigungsstufe korrekt löscht. Der einzige Grund, warum dies heute nicht möglich wäre, sind die offensichtlichen Leistungskosten für die Nachrüstung dieser Funktionalität auf bereits veröffentlichte Mikroarchitekturen über Mikrocode-Updates.
Fazit
Es ist sehr selten, dass ein Forschungsergebnis die Art und Weise, wie Computer gebaut und betrieben werden, grundlegend verändert. Meltdown und Spectre haben genau das getan. Diese Erkenntnisse werden das Hardware- und Softwaredesign in den nächsten 7 bis 10 Jahren (dem nächsten CPU-Hardwarezyklus) erheblich verändern, da die Designer die neue Realität der Möglichkeiten von Datenlecks über Cache-Seitenkanäle berücksichtigen.
In der Zwischenzeit werden die Ergebnisse von Meltdown und Spectre und die damit verbundenen Abhilfemaßnahmen für Computerbenutzer in den kommenden Jahren erhebliche Auswirkungen haben. Kurzfristig werden die Minderungen Auswirkungen auf die Leistung haben, die je nach Workload und spezifischer Hardware erheblich sein können. Dies kann betriebliche Änderungen für einige Infrastrukturen erforderlich machen (beispielsweise verschieben wir bei Lyft einige Workloads aggressiv auf AWS C5-Instances, da IBRS auf Skylake-Prozessoren wesentlich schneller zu laufen scheint und der neue Nitro-Hypervisor Interrupts direkt an Gäste liefert, die SR-IOV und APICv verwenden, wodurch viele Exits virtueller Maschinen für E / A-schwere Workloads entfernt werden). Desktop-Computer-Benutzer sind auch nicht immun, aufgrund von Proof-of-Concept-Browser-Angriffen mit JavaScript, an deren Abschwächung OS- und Browser-Anbieter arbeiten. Darüber hinaus ist es aufgrund der Komplexität der Sicherheitsanfälligkeiten fast sicher, dass Sicherheitsforscher neue Exploits finden, die nicht von den aktuellen Mitigationen abgedeckt werden, die gepatcht werden müssen.Obwohl ich es liebe, bei Lyft zu arbeiten und das Gefühl habe, dass die Arbeit, die wir im Bereich der Infrastruktur für Mikroservice-Systeme leisten, zu den wirkungsvollsten Arbeiten gehört, die derzeit in der Branche geleistet werden, lassen mich Ereignisse wie diese die Arbeit an Betriebssystemen und Hypervisoren vermissen. Ich bin extrem neidisch auf die heldenhafte Arbeit, die in den letzten sechs Monaten von einer großen Anzahl von Menschen bei der Erforschung und Minderung der Schwachstellen geleistet wurde. Ich wäre gerne ein Teil davon gewesen!
Weiterführende Literatur
- Meltdown und Spectre wissenschaftliche Arbeiten: https://spectreattack.com/
- Google Project Zero Blogbeitrag: https://googleprojectzero.blogspot.com/2018/01/reading-privileged-memory-with-side.html
- Intel Spectre Hardware mitigations: https://software.intel.com/sites/default/files/managed/c5/63/336996-Speculative-Execution-Side-Channel-Mitigations.pdf
- Retpoline blog post: https://support.google.com/faqs/answer/7625886
- Gute Zusammenfassung bekannter Informationen: https://github.com/marcan/speculation-bugs/blob/master/README.md