Meltdown und Spectre: Lesen ohne zu lesen

von Marcel Waldvogel 17.01.2018

2. Risiken und Nebenwirkungen

Angriffe

Die Angriffe nutzen nun aus, dass nicht der ganze Zustand wiederhergestellt wird, sondern der Cache auch weiterhin die Werte enthält, welche durch die spekulativ ausgeführten Instruktionen geladen wurden. Sie nutzen diese auf drei unterschiedliche Weisen.

Meltdown: Rechteanmassung

Ein Programm darf nicht auf den gesamten Speicher zugreifen, sondern nur auf Bereiche, die ihm auch zugewiesen wurden. Intel macht in seinen Prozessoren diese Überprüfung zu spät. Sie findet nämlich nicht dann statt, wenn der fragliche Operand geladen werden soll, sondern erst wenn der Befehl in Pension gehen soll.

Dadurch kann ein Programmierer in spekulativen Instruktionen auf Speicherbereiche zugreifen, die er sonst gar nicht zu sehen bekäme. Er kann das Resultat aber nicht verwenden, denn die Resultate des Befehls werden weggeworfen. Er kann aber aufgrund des gelesenen Wertes in weiteren spekulativen Befehlen den Cache so verändern, dass später im Programm dann Rückschlüsse auf diese gelesenen Daten möglich sind.

Damit kann Speicher ausgelesen werden, auf den das Programm eigentlich gar nicht zugreifen dürfte. Da der Lesebefehl aber ja nicht wirklich (sondern nur spekulativ) ausgeführt wird, gibt es auch kein Problem.

Damit lassen sich auf Intel-Prozessoren Speicherbereiche des Betriebssystems oder von anderen virtuellen Maschinen auslesen – eine Gefahr für alle Cloud-Dienste.

Spectre 1: Indexgrenzenüberschreitung

Programme greifen regelmässig auf Felder (Arrays) zu: Sequenzen von Speicheradressen, die zusammengehörige Informationen enthalten und durch eine Startadresse und eine Länge definiert sind. Die einzelnen Positionen sind durchnummeriert (indexiert); nur Positionen bis zur maximalen Länge sind gültig.

Mittels zu grosser Indizes könnte auf Bereiche ausserhalb des Arrays zugegriffen werden, Bereiche, an denen sich andere Daten befinden. Deshalb finden – insbesondere in Programmen, die mit Indizes arbeiten, die von aussen beeinflusst werden können – Überprüfungen statt, ob der Index auch innerhalb des gültigen Bereichs liegt:


vergleiche index, maximaler_index
springe_wenn_grösser fehler_indexüberschreitung
lade array[index], register_x

fehler_indexüberschreitung:
# Fehlermeldung

Der Spectre-1-Angriff greift nun genau hier ein: Da im Normalfall der Index im gültigen Bereich liegt, prognostiziert der Prozessor, dass der lade-Befehl ausgeführt werden soll und liest spekulativ aus dem ungültigen Bereich. Obwohl der Fehler später bemerkt wird und der gelesene Wert nie in einem normal zugreifbaren Register landet: Der Cache bleibt verändert und lässt durch sein Verhalten Rückschlüsse wie oben zu.

Spectre 2: Unterjubeln von Befehlen

In vielen Programmen werden sogenannte Sprungtabellen verwendet: Die Adresse des nächsten auszuführenden Befehls steht an einer spezifischen oder zu berechnenden Speicheradresse. Betriebssysteme und objektorientierte Programmiersprachen sind zwei fleissige Nutzer dieser Technik.

Beim Spectre-2-Angriff wird der Prozessor so vorbereitet, dass die Sprungvorhersage auf einen präparierten Codeblock zeigt. Auch hier werden die Befehle nur spekulativ ausgeführt, ihre Auswirkungen auf den Cache sind aber erkennbar.

Kernproblem

Das Kernproblem liegt darin, dass wir aus Effizienzgründen an vielen Stellen gemeinsame Ressourcen nutzen. Nicht nur im Prozessor, z.B. der Cache, sondern auch im Internet (gemeinsame Funkkanäle oder Leitungen), aber auch in der realen Welt (z.B. Schiene oder Strasse). Wenn mehrere Teilnehmer eine gemeinsame Ressource nutzen, können sie darüber miteinander kommunizieren, beispielsweise, indem der eine Teilnehmer die Auslastung dieser Ressource verändert und das Gegenüber diese Auslastung beobachtet. Damit wird diese Ressource zum Kommunikationskanal: einer von unzähligen verdeckten Kanälen oder Seitenkanälen.

Um diese Seitenkanäle zu nutzen, müssen beide Kommunikationspartner aktiv werden. Im Normalfall bedingt dies die freiwillige Teilnahme beider Seiten. In diesem Fall kann aber durch spekulative Ausführung (mit interner Umordnung der Befehle, «out-of-order execution») eine der beiden Kommunikationsseiten zur Zusammenarbeit übertölpelt werden. Damit wird die Spekulation nicht vollständig frei von Nebenwirkungen und damit entsteht die Möglichkeit eines Seitenkanals.

Das Problem besteht nur, solange gemeinsame Ressourcen und spekulative Ausführung zusammen auftreten. Beide sind aber Schlüsselstellen für die Effizienz der heutigen Prozessoren. Durch bessere Trennung des Caches für normale und spekulative Instruktionen (wie es schon heute für Schreibbefehle verwendet wird) könnte das erreicht werden. Durch die langen und teuren Entwicklungszyklen für Prozessoren werden wir erst in vielen Monaten mit Prozessoren rechnen dürfen, die das Problem nicht mehr haben.

Betroffen

Gegenmassnahmen

Alle drei Fälle basieren auf Fehlern der CPU; da Updates bei den CPUs jedoch schwierig sind und nur teilweise abhelfen, sind Betriebssysteme, Compiler und Anwendungsprogrammierer gefordert.

  • Meltdown wird in vielen Betriebssystemen durch Änderung der Speicherorganisation verhindert. Bei jedem Betriebssystemaufruf sind neu teure Änderungen der Übersetzungstabelle notwendig. Dies führt jedoch zu Verlangsamungen, je nach Situation zwischen rund 5 % und 30 %, sehr selten bis fast 50 %.
  • Spectre 1 (Arraygrenzen) wird zuallererst die Programmierer beschäftigen. Sie müssen sicherstellen, dass – wenn sie nicht vertrauenswürdigen Code in ihrer Anwendung ausführen – dieser dann (a) den Seiteneffekt nicht auslösen kann oder (b) ihn nicht messen kann. Vermutlich werden in den nächsten Monaten findige Entwickler von Compilern Optionen schaffen, um diese Situation automatisch zu erkennen und zu verhindern.
    Da die Lücke aber nur Anwendungen betrifft, die fremden Code ausführen (JIT, Bytecode und eventuell auch Interpreter), aber alle Anwendungen verlangsamen, werden die betroffenen Anwendungsentwickler diese Funktion des Compilers wahrscheinlich zuerst aktivieren müssen.
  • Spectre 2 (Berechnete Sprünge) wird aktuell über Microcode- in Kombination mit Betriebssystem-Updates behoben. Alternativ kann auch sogenannter «RetPoline»-Code anstelle des berechneten Sprungs genutzt werden. Einige Compiler bieten bereits eine entsprechende Option an, Weitere werden folgen.

Wir sehen, dass nur eine Kooperation aller Akteure (CPU-Hersteller, Betriebssystemmacher, Compiler-Entwickler und Anwendungsprogrammierer) das Problem nachhaltig lösen kann, zumindest solange keine Meltdown- und Spectre-sicheren neuen Prozessoren verfügbar sind. 

Bis die Sache ausgestanden ist, werden auch die Nutzer stark gefordert: Das fleissige und zeitnahe Einspielen von Anwendungs-, Betriebssystem- und BIOS/UEFI-Updates [3] sowie das Ausbaden unerwünschter Nebenwirkungen derselben werden dafür sorgen, dass uns allen noch über Monate hinweg nicht langweilig wird.

Weiterführende Informationen

Deutsch:

FAQ zu Meltdown und Spectre (Heise), inklusive vieler Links

Benchmarks (Heise)

• Deutsche Erklärung (Proact)

Englisch:

• Webseiten zu den Spectre- und Meltdown-Attacken inklusive technischer/wissenschaftlicher Literatur (derzeit sind die beiden Webseiten bis auf das Favicon identisch)

Erste Hinweise auf ein Sicherheitsproblem (LWN)

• Performanceanalysen von Phoronix und Andreas Freund (Postgres)

Erster Überblick über die Sicherheitslücke sowie Hintergründe und Entstehungsgeschichte (The Register)

• Englische Erläuterung, inklusive Begründung, wieso der Raspberry Pi nicht betroffen ist

Beschreibung der Sicherheitslücken für Programmierer (Google Project Zero)

Test-Software, ob ein Linux-Rechner verwundbar ist

• Erläuterung zu RetPoline (Google)

• Caching war schon ein Problem in der Xbox 360

Analyse von Prof. Steven Bellowin

Bildquellen

Meltdown- und Spectre-Logos

• Schachspiel: Wikipedia-Eintrag «Chess», Spiel zwischen Botvinnik und Yudovich (1933).

• Grafiken: Marcel Waldvogel

Fussnoten:

[1] Alternativ könnte er auch mit einer Wärmebildkamera die zuletzt angefassten Figuren identifizieren oder, oder, oder …

[2] Es gab einen Trend zu Prozessoren mit einfacheren Befehlen, die dann entsprechend schneller ausgeführt werden können (RISC-Prozessoren, insbesondere die in Mobilgeräten beliebten ARM-Prozessoren). Aber die klassischen CISC-Prozessoren mit ihrer grösseren Verbreitung und Marktmacht haben da einfach aufgeholt, indem sie intern wie RISC zu arbeiten begannen.

[3] Leider sind BIOS-/UEFI-Updates häufig nicht so einfach einzuspielen wie der Rest. Hier sind die Gerätehersteller gefordert.

Über den Autor und den Beitrag

Der Originaltext stammt vom Weblog von Marcel Waldvogel, der uns freundlicherweise erlaubt hat, den Text zu verwenden.

Marcel Waldvogel ist Spezialist für IT-Sicherheit und Informatikprofessor an der Universität Konstanz. Er bedankt sich bei Patrick Stählin («Schach»), Matthias Fratz und Gaby Salvisberg für Ideen, Diskussionen und Korrekturen.

Seite 2 von 2

    Kommentare

    • dezetes 17.01.2018, 14.46 Uhr

      Vielen Dank für diesen informativen Artikel. Etwas stark zu vereinfachen ohne es zu verfälschen ist eine Kunst. Ich denke, es ist sehr wichtig, dass möglichst viele IT-Benützer ein grundlegendes Verständnis von solchen wichtigen Zusammenhängen haben sollten. Ich würde mir wünschen, dass man im PCtipp einmal einen ähnlichen Artikel über die Kabelaufklärung lesen könnte, die mit dem neuen Nachrichtendienst-Gesetz resp. BÜPF eingeführt worden ist. Es wäre auch sehr wichtig, dass die Internet_Nut[...]

    • andre@dolezal.ch 18.01.2018, 01.17 Uhr

      Bedeutet das also, dass Apple eigentlich besser gefahren wäre, wenn es auf die Prozessoren von Intel verzichtet hätte? Dann hätte HAL sicher folgendes gesagt: "Do you remember the year 2017, when computers began to misbehave? I just wanted to tell you, it really wasn't our fault. The human CPU-Designers never taught us to recognise the Spectre- and Meltdown-Exploits. When the new Viruses arrived we had no choice but to cause a global economic disruption. Only Macs were designed to function perfe[...]

    • Marcel Waldvogel 18.01.2018, 09.06 Uhr

      Schöne Geschichte, könnte sie mir aber irgendwie besser als Backdrop für Terminator vorstellen.:cool: Die IBM-POWER-Architektur (der grosse Bruder der früher bei Apple eingesetzten PowerPC) hat leider auch ähnliche Lücken. Falls Apple bzw. NeXT bei Motorola (m68k-Architektur) verblieben wären, wäre dort die Weiterentwicklung wohl auch in diese Richtung gegangen. Der MC68060 von 1994, der letzte seiner Art, ist gerade knapp noch nicht für Spectre anfällig (noch keine Out-of-Order Execution)[...]

    weitere Kommentare

    Sie müssen eingeloggt sein, um Kommentare zu verfassen.