Frage zu Meltdown



  • Tobiking2 schrieb:

    hustbaer schrieb:

    Und wenn man das Permission-Bit im gleichen Schritt bekommt wie die physikalische Adresse, kann man das Permission-Bit doch auch genauso gut checken bevor man anfängt die Cacheline zu laden.

    Damit führst du den Check aber gegen den Zustand zum Zeitpunkt des Ladens in den Cache aus. Dann musst du wieder sicherstellen, dass sich bis zum Zeitpunkt des Ausführen des Read Befehls das Ergebnis nicht ändert oder den Check erneut ausführen. Aber keine Ahnung wie Aufwändig das Ganze dann wird.

    Ah, ja, stimmt.

    Ich denke das sollte sich aber mit vertretbarem Overhead fixen lassen. Im Prinzip braucht man ja nur ne Dependency zwischen Kernel-Memory Zugriffen und Befehlen wie syscall & Co.



  • computertrolls schrieb:

    hustbaer schrieb:

    Dass das vermutlich nicht mit einem Microcode Update zu beheben sein wird ist auch klar, aber zukünftigen CPU Generationen müsste man das doch beibringen können.

    Mich würde ja interessieren, wie lange Intel dazu benötigen wird, eine neue CPU Generation ohne diesen Bug auf den Markt zu bringen.

    Um Meltdown zu fixen ist sicher keine grundlegend neue Microarchitektur nötig.

    Bei Spectre könnte es schwieriger werden. Falls man für Spectre allerdings immer den Branch-Target-Buffer braucht, um die Speculative-Execution im Ziel-Process an eine bestimmte Stelle zu lenken, dann sollte das IMO auch relativ leicht dadurch fixbar sein dass man jedem Hardware Thread einen eigenen Branch-Target-Buffer spendiert.

    Aber um Spectre geht's mir erstmal nicht, dazu möchte ich erst noch mal das Paper lesen und mir in Ruhe ein paar Gedanken dazu machen. Weswegen ich hier ja auch konkret nach Meltdown gefragt habe und nicht nach Spectre.



  • Tobiking2 schrieb:

    hustbaer schrieb:

    Und wenn man das Permission-Bit im gleichen Schritt bekommt wie die physikalische Adresse, kann man das Permission-Bit doch auch genauso gut checken bevor man anfängt die Cacheline zu laden.

    Damit führst du den Check aber gegen den Zustand zum Zeitpunkt des Ladens in den Cache aus. Dann musst du wieder sicherstellen, dass sich bis zum Zeitpunkt des Ausführen des Read Befehls das Ergebnis nicht ändert oder den Check erneut ausführen. Aber keine Ahnung wie Aufwändig das Ganze dann wird.

    Verstehe den Einwand nicht. Wenn sich die page table während des Ladens ändert (wie soll das gehen?) wäre ja auch die physikalische Adresse hinfällig.
    Wenn sich der Inhalt des Speichers ändert, ist das von der physikalischen Adresse und permission unahbhängig und ein anderes Problem.

    Noch ne andere Frage zu Meltdown:
    Wozu wird zunächst eine exception generiert?
    Wenn erst die Speicherstelle gelesen und dann die permission geprüft wird, muss das Ganze doch auch direkt funktionieren?
    Was hat das mit instruction reordering zu tun?



  • C14 schrieb:

    Verstehe den Einwand nicht. Wenn sich die page table während des Ladens ändert (wie soll das gehen?) wäre ja auch die physikalische Adresse hinfällig.
    Wenn sich der Inhalt des Speichers ändert, ist das von der physikalischen Adresse und permission unahbhängig und ein anderes Problem.

    Die CPU kann dazwischen in den Supervisor Mode wechseln oder aus dem Supervisor Mode zurück in den User Mode.

    C14 schrieb:

    Noch ne andere Frage zu Meltdown:
    Wozu wird zunächst eine exception generiert?

    Beliebig. z.B. Division durch null. Kann sich der Angreifer aussuchen.

    C14 schrieb:

    Wenn erst die Speicherstelle gelesen und dann die permission geprüft wird, muss das Ganze doch auch direkt funktionieren?
    Was hat das mit instruction reordering zu tun?

    Mit Speculative Execution und dem Cache hat es zu tun. Is aber a bissi viel um es in an Forums-Posting zu erklären. Lies das Paper: https://meltdownattack.com/meltdown.pdf



  • C14 schrieb:

    Wozu wird zunächst eine exception generiert?

    Soweit ich es verstanden habe erhöht die Exception die Zeit zwischen dem Read und dem Permission Check. Google gibt als Alternative eine Branch-Misprediction an. Ist aber nicht so leicht zu generieren. Grundsätzlich muss der Zeitraum muss groß genug sein um ein weiteren Read auszuführen.

    C14 schrieb:

    Wenn erst die Speicherstelle gelesen und dann die permission geprüft wird, muss das Ganze doch auch direkt funktionieren?
    Was hat das mit instruction reordering zu tun?

    Der grundlegende Trick ist:

    X = Lese Wert aus Kernelspace
    Y = Lese Wert aus A + X * Cacheline
    Für i=0...
      Messe Zeit für Zugriff auf A + i * Cacheline
      Wenn Zeit == Cachezugriff => X = i
    

    Und das geht nur wenn die Abfolge der Befehle intern folgendermaßen aussieht:

    1. Lese Wert aus Kernelspace
    2. Lese Wert aus A + X * Cacheline
    3. Prüfe ob 1. erlaubt war => Abbruch von 1. bzw. Verwerfen des Ergebnisses

    Würde 3. vor 2. passieren würde A + X * Cacheline nicht im Cache landen.



  • Oh ok, man braucht ja beide Instruktionen 🙄
    Danke für die gute Zusammenfassung, Tobiking2!



  • Wie lang braucht man dann, um irgendwas sinnvolles damit auszulesen?
    Wenn man das Video hier anschaut bei ca. 5:45, dann ist das relativ langsam für ein paar Wörter.
    https://www.youtube.com/watch?v=I5mRwzVvFGE

    Das würde ja ewig dauern, da ein MB oder GB auszulesen. Gibt es dazu Werte?



  • Zeit??? schrieb:

    Wie lang braucht man dann, um irgendwas sinnvolles damit auszulesen?
    Wenn man das Video hier anschaut bei ca. 5:45, dann ist das relativ langsam für ein paar Wörter.
    https://www.youtube.com/watch?v=I5mRwzVvFGE

    Das würde ja ewig dauern, da ein MB oder GB auszulesen. Gibt es dazu Werte?

    Im Paper steht etwas von 503 kb/s maximal. Gezeigte Proof of Concepts zu Spectre und Meltdown haben aber teilweise auch nur 1-2 kb/s. Und je nach Variante muss der richtige Speicherbereich noch gesucht werden, was mit 10-30 Minuten (bei 64 gb RAM) angegeben ist.

    Es ist schon nur dafür geeignet gezielt Passwörter oder Private Keys auszulesen.



  • Man muss doch für jedes bit, das man auslesen will, immer wieder den Cache flushen. Sollte ja relativ einfach sein, die Anzahl der Cache flushes zu zählen und wenn ein Programm extrem viele macht, wird es vom OS beendet.



  • SW Fix schrieb:

    Man muss doch für jedes bit, das man auslesen will, immer wieder den Cache flushen.

    Du musst nicht den ganzen Cache flushen - es reicht die Cache-Lines rauszuwerfen die du für die Überprüfung brauchst. Bei nem einzelnen Bit sind das bloss zwei bzw. evtl. sogar nur eine.
    Bei einem 16-fach assoziativ Cache wie von z.B. Skylake müsstest du dazu bloss 32 bzw. 16 andere Cache-Lines laden. Sollte schneller gehen als den ganzen Cache wegzuwerfen.

    SW Fix schrieb:

    Sollte ja relativ einfach sein, die Anzahl der Cache flushes zu zählen und wenn ein Programm extrem viele macht, wird es vom OS beendet.

    Nur dass man den Cache nicht flushen muss, siehe oben. Bzw. selbst wenn man müsste, dann wäre das etwas was vielleicht ein Virenscanner bei entsprechend paranoiden Einstellungen machen könnte, aber sicher nicht das OS. Ich hätte zumindest keine Freude damit wenn das OS einfach so beschliesst Programme zu killen - trotz dem diese nichts explizit verbotenes machen.
    (BTW: Ich weiss nichtmal ob die zum Flushen des Cache nötigen Befehle überhaupt im Usermode ausgeführt werden dürfen. Ich gehe einfach mal davon aus dass ja, denn wenn nein, dann ist die Überlegung sowieso hinfällig. Denn dann bleibt sowieso nur das Überschreiben mittels Laden von anderen Cache-Lines.)



  • Tobiking2 schrieb:

    Im Paper steht etwas von 503 kb/s maximal.

    ~500 kB/s mit Meltdown auf CPUs die Hardware Transactional Memory unterstützen.
    Ansonsten mit Meltdown ca. 1/4 davon.

    Tobiking2 schrieb:

    Gezeigte Proof of Concepts zu Spectre und Meltdown haben aber teilweise auch nur 1-2 kb/s.

    Mit Spectre wird man viel viel langsamer sein. Bei Meltdown sollte man aber auf die angegebenen Werte kommen - die haben sich die Jungs ja schliesslich nicht aus den Fingern gesaugt.


Anmelden zum Antworten