NX-Bit ist nicht nur für Sicherheit da

The NX bit is not just about security

In diesem Gastbeitrag erzählt Sonya, wie sie einen scheinbar unmöglichen Bug in einem ARM64-Hypervisor für postmarketOS jagte. Das Einschalten des CTR_EL0-Intercepts ließ das Telefon zufällig einfrieren. Nachdem sie Hypothesen wie falsche Emulation oder fehlerhafte Hardware ausgeschlossen hatte, entdeckte sie durch Binär-Bisektion einen Unterschied zwischen dynamischen und statischen Sprüngen. Der Verdacht fiel auf spekulative Ausführungen, die zu einem Nullzeiger führten – ein Problem, das über die übliche Sicherheitsperspektive des NX-Bits hinausgeht.

Wie unterscheiden sich dynamische Dispatches von statischen Verzweigungen? Dynamische Dispatches nutzen Sprungvorhersage, statische Verzweigungen wissen vorab, wohin sie führen, und können nicht fehlvorhersagen.
  1. repiret

    "Spekulativer Befehlsabruf aus Gerätespeicher stürzt das Gerät ab" steht auf meiner Liste der besten je gefundenen Bugs. Ich bin darauf auf einem Cortex-M4 ohne MPU gestoßen, sodass ich nicht einmal die Speicherattribute ändern konnte; die einzige Lösung war, den kompilierten Code so zu manipulieren, dass der spekulative Abruf verhindert wird.

    Es ist verrückt, dass Armv8/9-A spekulative Befehlsabrufe aus Gerätespeicher zulässt. So verrückt, dass ich es nachschlagen musste, um es zu glauben:

    "Die Hardware verhindert spekulative Befehlsabrufe aus einer Speicherstelle mit einem der Device-Speicherattribute nicht, es sei denn, die Speicherstelle ist auch für alle Ausnahmeebenen als execute-never markiert." - ARM DDI 0487K.a § B2.15.2

    Die Armv7-M-Spezifikation ist weniger klar. Sie sagt zwar: "Die Architektur erlaubt keine spekulativen Zugriffe auf als Device markierten Speicher", im Gegensatz zu Armv8/9-A, die eine ähnliche Aussage mit "Datenzugriffe" qualifiziert. Aber später sagt sie: "Um die Korrektheit zu gewährleisten, müssen leseempfindliche Stellen als nicht ausführbar markiert werden." (Dies alles aus ARM DDI 0403E.e § A3.5.7)

    Ich habe kein älteres v7-A zur Hand, um zu vergleichen, was sie sagen.

  2. asveikau

    Zu diesem Thema, dass es nicht nur um Sicherheit geht: Wenn Sie einen Fehler wie Use-after-Free haben und dieser zufällig einen Funktionszeiger betrifft, kann das NX-Bit sicherstellen, dass Sie beim Verfolgen dieses Zeigers durch einen Aufruf einen sauberen Trap so nah wie möglich an der Fehlerstelle erhalten. Wenn es blind veraltete Bytes als Code ausführen würde, sähe der Absturz und der Stack-Trace vielleicht nicht so schön aus.

    Aber viele Korrektheitsfehler dieser Art sind auch Sicherheitsprobleme.

  3. mubbicles

    Ich habe diesen Artikel geschätzt. Ich habe unseren CSP-Mitarbeiter nach dem Unterschied gefragt, aber das hilft mir, Device vs. NS besser zu verstehen. Ich schätze auch, dass dies nicht KI-geschrieben zu sein scheint.

  4. anyfoo

    Heutzutage gilt es als schlechter Stil, irgendetwas bei 0 zu mappen ... Sie kennen jetzt einen der Gründe dafür!

    In dem Fall, den ich kenne und der eine 1:1-Identitätsabbildung des Adressraums hat, hat der physische Adressraum tatsächlich auch nichts bei 0, sodass es immer noch nicht gemappt werden muss.

  5. eqvinox

    Ehrlich gesagt fühlt es sich wie ein Fehlentwurf in ARM an. Wo ergibt es jemals Sinn, dass Device-Speicher nicht Daten-Prefetchbar ist, aber Befehls-Prefetch erlaubt? Es sollte meiner Meinung nach jegliches Prefetch deaktivieren ...

Mehr von diesem Tag

2026-09-07