04 Januar 2018

Der Prozessor als Sicherheitsleck

Kategorien: Aktuelles PostgreSQL
Tags: Kernel Linux Meltdown PostgreSQL Spectre

Mit Beginn des Jahres 2018 wurden Probleme mit dem Speichermanagement und Intel-Prozessoren öffentlich. Laut diesen Reports ist es offensichtlich möglich, beliebige Bereiche des Kernel- und Userspace Speicherbereiches auszulesen und damit unter Umständen auf sensitive Bereiche zugreifen zu können.

Im Laufe der letzten Tage gab es einige Gerüchte und Vermutungen, in welche Richtung dies alles geht, mittlerweile gibt es ein offizielles Statement der Hacker von Project Zero (Google), die die Erkenntnisse zusammenfassen.

Was ist genau passiert?

Im wesentlichen wurden Angriffsvektoren identifiziert, die über die nicht erfolgreiche, spekulative Ausführung von Code auf einem Prozessor und geschicktes Timing privilegierte Informationen trotz fehlender Berechtigung aus dem Cache der CPU auslesen kann. Hierbei ist es möglich, trotz der fehlenden Berechtigung (sei es aus dem User- oder innerhalb des Kernelspace) Speicherbereiche zu lesen und deren Inhalte zu interpretieren. Dies ermöglich theoretisch breitflächige Einfallstore für Schadsoftware, wie etwa das Auspionieren sensibler Daten oder der Mißbrauch von Berechtigungen. Man spricht hier von sogenannten Side Channel Attacks. Betroffen sind nach aktuellem Kenntnisstand nicht nur Intel CPUs (von denen man ausschließlich ursprünglich ausging), sondern auch AMD CPUs, ARM sowie POWER8 und 9 Prozessoren.

Was genau geschieht aktuell?

Project Zero fasst im Report die wesentlichen Probleme zusammen. Es existieren mehrere Exploits die mit unterschiedlichen Ansätzen privilegierte Speicherbereiche lesen und damit unberechtigterweise an Informationen in sensiblen Bereichen des Kernels oder anderer Prozesse gelangen können. Da fast alle modernen CPUs die spekulative Ausführung von Anweisungen unterstützen, um ein Leerlaufen ihrer Ausführungseinheiten und damit verbundene hohe Latenzen zu verhindern, sind eine Vielzahl von Systemen theoretisch betroffen. Ein weiterer Ansatzpunkt dieses Angriffsszenarios ist die in aktuellen Systemen vorhandene Art und Weise, wie die Speicherbereiche von User- und Kernelspace interagieren. Tatsächlich war es bisher so, dass diese Speicherbereiche nicht wirklich voneinander getrennt sind, sondern der Zugriff auf diese Bereiche mit einem speziellen Bit abgesichert sind. Der Vorteil dieser nicht vorhandenen Trennung sind insbesondere dann tragend, wenn beispielsweise häufig von User- auf Kernelspace umgeschaltet werden muss.

Die Angriffsszenarien im Einzelnen sind:

  • Spectre

Dieses Angriffsszenario nutzt die in modernen CPUs vorhandene Branch Prediction, d.h. Vorabanalyse über die Wahrscheinlichkeit dass bestimmter Code bzw. -zweige erfolgreich ausgeführt werden können. Hierbei wird die CPU dazu verleitet eigentlich von der Vorhersage nicht berücksichtigten Code spekulativ auszuführen. Diese Attacke kann dann benutzt werden, um schadhaften Code auszuführen. Diese Attacke funktioniert theoretisch auf allen CPUs mit entsprechender Sprungvorhersage, allerdings ist es laut Project Zero hier schwer zusammenfassend zu sagen welche Prozessoren in welcher Art betroffen sind. Spectre hat vor allem Anwendungen im Userspace im Fokus. Da Spectre hauptsächlich dann funktioniert, wenn bereits fehlerhafter Code in entsprechenden Anwendungen vorhanden ist, sollte besonders auf entsprechende Updates geachtet werden.

  • Meltdown

Bei Meltdown wird nun die spekulative Ausführung genutzt, um Code auszuführen, der eigentlich gar nicht final erreicht werden kann. Dies sind hier Exception-Anweisungen mit nachfolgenden Instruktionen, die nie ausgeführt würden. Durch die spekulative Ausführung der CPU werden diese Instruktionen dennoch von der CPU berücksichtigt. Zwar gibt es keine Seiteneffekte durch diese Art der Ausführung, dennoch verbleiben die von der Instruktion belegten Speicheradressen im Cache der CPU und können von dort genutzt werden, um alle Speicheradressen zu testen. Da aktuell der Speicherbereich des Kernels und des Userspaces gleichermaßen zusammenhängend organisiert sind, kann so nicht nur der gesamte Speicherbereich des Kernels, sondern auch aller auf dem System laufenden Prozesse ausgelesen werden. Eine detaillierte Beschreibung der Funktionsweise des Angriffs ist hier zu finden. Meltdown funktioniert nur auf Intel Prozessoren, da nur hier die Privilegien auf den adressierten Speicherbereich bei Out-Of-Order Ausführung nicht mehr geprüft werden.

Beide Szenarios machen sich auf unterschiedliche Art und Weise die entsprechenden Sicherheitslücken zunutze. Die CVEs zu den Lücken sind im einzelnen:

Wie geht es weiter?

Um Meltdown-Attacken vorzubeugen gibt es für Linux, Windows und OSX bereits entsprechende Updates (Letzteres enthält entsprechende Änderungen bereits seit geraumer Zeit. Im wesentlichen trennen diese Updates die Speicherverwaltung für den Kernel- und Userspace völlig auf (unter Linux bekannt als KPTI-Patches, Kernel Page Table Isolation, formals auch KAISER). Hierdurch ist es nicht mehr möglich, durch die Privilege Escalation auf Intelprozessoren auf Speicherbereiche des Kernels ausgehend eines unprivilegierten Kontextes zuzugreifen. RedHat stellt diese ebenso wie CentOS und Fedora bereits mit aktualisierten Kerneln zur Verfügung.

Insbesondere die Meltdown-Attacken werden hierbei wirkungsvoll unterdrückt, für Spectre-Attacken selbst gibt es ausgehend der aktuellen Sachlage keine belastbaren, wirkungsvollen Maßnahmen. Wichtig ist jedoch, dass im Linuxkernel eBPF und die entsprechende Ausführung vom BPF-Code im Kernel deaktiviert wird.

sysctl -a | grep net.core.bpf_jit_enable
sysctl net.core.bpf_jit_enable=0

Die Änderung setzt „root“-Berechtigungen voraus.

Geschwindigkeit aktualisierter Kernel

Durch die Trennung der Speicherverwaltung für Kernel- und Userspace werden Kontextwechsel und Systemaufrufe teurer. Dies sorgt für deutlich höhere Latenzen, insbesondere wenn die Anwendung sehr viele Kontextwechsel (beispielsweise Netzwerkommunikation) verursacht. Die Einbußen hierbei sind schwierig zu bemessen, da nicht jeder Workload wirklich identische Zugriffsmuster zugrunde legt. Für kritische Systeme empfehlen sich daher Lasttests auf identischen Testsystemen falls möglich. Falls nicht möglich sollten die Lastparameter nach der Aktualisierung des Systems sorgfältig beobachtet werden. Man nimmt pauschal Geschwindigkeitseinbußen im Rahmen 5% an, letztendlich wurden jedoch auch Tests der Kernelentwickler mit bis zu 30% Einbußen beobachtet. Da die Page Table Isolation (bis jetzt) nur für x86_64 Architekturen verfügbar ist, treffen diese Zahlen tatsächlich nur auf Maschinen mit Intel Prozessoren zu. Tatsächlich wird KPTI vom Kernel Upstream standardmässig nicht für AMD aktiviert.

Ob KPTI aktiviert ist, lässt sich per Kernel-Log ermitteln:

dmesg -T | grep "page tables isolation"
[Fr Jan  5 10:10:16 2018] Kernel/User page tables isolation: enabled

Insbesondere Anwender von Datenbanken sind hier sensitiv, da zum Beispiel Systeme wie PostgreSQL in der Regel eine hohe Anzahl Context Switches bei hoher Last verursachen. Bei credativ haben wir den Impact auf einem kleinen virtualisierten System klassifiziert. Grundlage ist ein Fedora 27 System als KVM-Gast mit 4 GByte RAM und schnellem NVMe-Speicher als Grundlage. Dies spielt bei diesem Test jedoch eher ein unbedeutende Rolle, da die mit pgbench durchgeführten Datenbanktests lediglich eine Größe von knapp 750 MByte hat. Der Shared Buffer Pool der PostgreSQL Instanz war mit 1 GByte so konfiguriert, dass die komplette Datenbank in den Datenbankcache passt. Die Tests wurden jeweils mit 4 und 8 virtuellen Prozessoren durchgeführt. Das Hostsystem verfügt über einen Intel Core i7-6770HQ Prozessor.

Die größte Auswirkung ist zu beobachten, wenn PCID im Kernel nicht vorhanden bzw, deaktiviert ist. PCID ist eine Optimierung, die einen Flush des Translation Lookaside Buffers (TLB) verhindert, wenn ein Context Switch erfolgt. Virtuelle Speicheradressen werden nur dann erfolgreich per TLB aufgelöst, wenn die PCID zum aktuellen Thread auf der jeweiligen CPU passt. PCID steht ab kernel 4.14 zur Verfügung. Der Test vergleicht einen Entwicklerkernel mit Page Table Isolation (PTI) 4.15.0-rc6, aktuellen Fedora Upstreamkernel mit und ohne Sicherheitspatches. PTI kann deaktiviert werden, indem man dem Kernel mittels pti=off beim Booten ein entsprechendes Argument definiert.

Das Fedora Testsystem hat bereits einen sehr aktuellen Kernel (4.14). Der Unterschied zum alten Upstreamkernel 4.14.8 ohne Sicherheitsrelevante Patches beträgt zum neuen Kernel 4.14.11 ca. 6%. pgbench liefert dann folgende Durchsatzraten (Transaction per second):

TPS_KPTI

Legt man den ehemaligen Standardkernel 4.14.8 von Fedora 27 mit 100% zugrunde, ergibt sich folgendes Bild:

Percent_Kernels_KPTI

Die PostgreSQL Community hat ebenfalls bereits kleinere Tests zum Messen der Auswirkungen durchgeführt. Die Ergebnisse decken sich mit unseren Erkenntnissen. Der neue Kernel 4.14.11 mit den relevanten Patches bietet in etwa diesselbe Performance wie der Entwicklerkernel 4.15.0-rc6 auf dieser Plattform. 4.14.11 ist in diesen Testcases sogar teilweise vor dem alten Upstreamkernel (8 vCPU, Vergleich 4.14.8, grün und 4.14.11, braun). Allerdings liegt der Vorteil hier bei knapp über 1%, so dass man hier eher davon ausgehen kann, dass bei dieser Teststellung keine großen Geschwindigkeitsunterschiede bestehen.

Für Interessierte gibt es zudem eine eigene Seite zu dem Thema. Diese fasst alle wesentliche Informationen zusammen. Empfehlenswert ist auch die Zusammenfassung des Journalisten Hanno Böck auf github, die eine sehr gute Liste aller Patches für Meltdown und Spectre bietet.

Kategorien: Aktuelles PostgreSQL
Tags: Kernel Linux Meltdown PostgreSQL Spectre


Beitrag teilen: