ShadowCallStack (SCS) ist ein LLVM-Instrumentierungsmodus , der vor dem Überschreiben von Rücksendeadressen (wie z Epilog. Die Rücksendeadresse wird aus Gründen der Kompatibilität mit Unwindern ebenfalls auf dem regulären Stack gespeichert, wird aber ansonsten nicht verwendet. Dadurch wird sichergestellt, dass Angriffe, die die Rücksendeadresse auf dem regulären Stapel ändern, keine Auswirkungen auf den Programmkontrollfluss haben.
Auf aarch64 verwendet die Instrumentierung das x18
Register, um auf den ShadowCallStack zu verweisen, was bedeutet, dass Verweise auf den ShadowCallStack nicht im Speicher gespeichert werden müssen. Dadurch ist es möglich, eine Laufzeit zu implementieren, die es vermeidet, die Adresse des ShadowCallStacks Angreifern preiszugeben, die beliebigen Speicher auslesen können.
Implementierung
Android unterstützt ShadowCallStack sowohl für den Kernel als auch für den Userspace.
Aktivieren von SCS für den Kernel
Um ShadowCallStack für den Kernel zu aktivieren, fügen Sie der Kernel-Konfigurationsdatei die folgende Zeile hinzu:
CONFIG_SHADOW_CALL_STACK=y
Aktivieren von SCS im Benutzerbereich
Um ShadowCallStack in Userspace-Komponenten zu aktivieren, fügen Sie die folgenden Zeilen zur Blueprint-Datei einer Komponente hinzu:
sanitize: { scs: true }
SCS geht davon aus, dass das x18
Register zum Speichern der Adresse des ShadowCallStack reserviert ist und nicht für andere Zwecke verwendet wird. Während alle Systembibliotheken kompiliert werden, um das x18
Register zu reservieren, ist dies möglicherweise problematisch, wenn SCS für Userspace-Komponenten aktiviert ist, die mit prozessinternem Legacy-Code interagieren (z das x18
Register. Daher empfehlen wir, SCS nur in eigenständigen Komponenten zu aktivieren, die nicht in Legacy-Binärdateien geladen werden.
Validierung
Es gibt keinen CTS-Test speziell für SCS. Stellen Sie stattdessen sicher, dass CTS-Tests mit und ohne aktiviertem SCS bestanden werden, um sicherzustellen, dass SCS das Gerät nicht beeinträchtigt.