Integer-Überlaufbereinigung

Unbeabsichtigte Ganzzahlüberläufe können zu Speicherbeschädigungen oder Schwachstellen bei der Offenlegung von Informationen in Variablen führen, die mit Speicherzugriffen oder Speicherzuweisungen verbunden sind. Um dem entgegenzuwirken, haben wir Clangs UndefinedBehaviorSanitizer (UBSan) signierte und unsignierte Integer-Überlauf-Bereinigungen hinzugefügt, um das Medien-Framework in Android 7.0 zu härten . In Android 9 haben wir UBSAN erweitert, um mehr Komponenten abzudecken, und die Unterstützung für Build-Systeme dafür verbessert.

Dies wurde entwickelt, um Überprüfungen um arithmetische Operationen / Anweisungen hinzuzufügen, die überlaufen könnten, um einen Prozess sicher abzubrechen, wenn ein Überlauf auftritt. Diese Bereinigungsprogramme können eine ganze Klasse von Schwachstellen durch Speicherbeschädigung und Offenlegung von Informationen mindern, bei denen die Hauptursache ein Ganzzahlüberlauf ist, wie z. B. die ursprüngliche Stagefright-Schwachstelle.

Beispiele und Quelle

Integer Overflow Sanitization (IntSan) wird vom Compiler bereitgestellt und fügt der Binärdatei während der Kompilierzeit Instrumente hinzu, um arithmetische Überläufe zu erkennen. Es ist standardmäßig in verschiedenen Komponenten auf der gesamten Plattform aktiviert, zum Beispiel /platform/external/libnl/Android.bp .

Implementierung

IntSan verwendet UBSans vorzeichenbehaftete und vorzeichenlose Integer-Überlauf-Bereinigungsprogramme. Diese Minderung wird auf Modulebene aktiviert. Es trägt dazu bei, kritische Komponenten von Android zu schützen und sollte nicht deaktiviert werden.

Wir empfehlen Ihnen dringend, die Integer Overflow Sanitization für zusätzliche Komponenten zu aktivieren. Ideale Kandidaten sind privilegierter nativer Code oder nativer Code, der nicht vertrauenswürdige Benutzereingaben parst. Mit dem Bereinigungsprogramm ist ein geringer Leistungsaufwand verbunden, der von der Verwendung des Codes und der Verbreitung arithmetischer Operationen abhängt. Erwarten Sie einen kleinen Overhead-Prozentsatz und testen Sie, ob die Leistung ein Problem darstellt.

Unterstützung von IntSan in Makefiles

Um IntSan in einem Makefile zu aktivieren, fügen Sie Folgendes hinzu:

LOCAL_SANITIZE := integer_overflow
# Optional features
LOCAL_SANITIZE_DIAG := integer_overflow
LOCAL_SANITIZE_BLACKLIST := modulename_blacklist.txt
  • LOCAL_SANITIZE eine durch Kommas getrennte Liste von Bereinigungsmitteln, wobei integer_overflow ein vorgefertigter Satz von Optionen für die einzelnen vorzeichenbehafteten und unsignierten Ganzzahlüberlauf-Bereinigungsmittel mit einer standardmäßigen schwarzen Liste ist .
  • LOCAL_SANITIZE_DIAG den Diagnosemodus für die Desinfektionsmittel. Verwenden Sie den Diagnosemodus nur während des Testens, da dieser bei Überläufen nicht abgebrochen wird, wodurch der Sicherheitsvorteil der Minderung vollständig zunichte gemacht wird. Weitere Einzelheiten finden Sie unter Fehlerbehebung .
  • LOCAL_SANITIZE_BLACKLIST können Sie eine Blacklist-Datei angeben, um zu verhindern, dass Funktionen und Quelldateien bereinigt werden. Weitere Einzelheiten finden Sie unter Fehlerbehebung .

Wenn Sie eine genauere Steuerung wünschen, aktivieren Sie die Desinfektionsmittel einzeln mit einem oder beiden Flags:

LOCAL_SANITIZE := signed-integer-overflow, unsigned-integer-overflow
LOCAL_SANITIZE_DIAG := signed-integer-overflow, unsigned-integer-overflow

Unterstützung von IntSan in Blueprint-Dateien

Fügen Sie Folgendes hinzu, um die Bereinigung von Ganzzahlüberläufen in einer Blaupausendatei wie /platform/external/libnl/Android.bp zu aktivieren:

   sanitize: {
      integer_overflow: true,
      diag: {
          integer_overflow: true,
      },
      blacklist: "modulename_blacklist.txt",
   },

Wie bei Make-Dateien handelt es sich bei der integer_overflow -Eigenschaft um einen vorgefertigten Satz von Optionen für die einzelnen signierten und unsignierten Integer-Überlaufbereinigungen mit einer standardmäßigen Blacklist .

Der diag -Eigenschaftensatz aktiviert den Diagnosemodus für die Desinfektionsmittel. Verwenden Sie den Diagnosemodus nur während des Testens. Der Diagnosemodus wird bei Überläufen nicht abgebrochen, wodurch der Sicherheitsvorteil der Risikominderung in Benutzerbuilds vollständig zunichte gemacht wird. Weitere Einzelheiten finden Sie unter Fehlerbehebung .

Die blacklist -Eigenschaft ermöglicht die Angabe einer Blacklist-Datei, mit der Entwickler verhindern können, dass Funktionen und Quelldateien bereinigt werden. Weitere Einzelheiten finden Sie unter Fehlerbehebung .

Um die Desinfektionsmittel einzeln zu aktivieren, verwenden Sie:

   sanitize: {
      misc_undefined: ["signed-integer-overflow", "unsigned-integer-overflow"],
      diag: {
          misc_undefined: ["signed-integer-overflow",
                           "unsigned-integer-overflow",],
      },
      blacklist: "modulename_blacklist.txt",
   },

Fehlerbehebung

Wenn Sie die Integer-Überlauf-Bereinigung in neuen Komponenten aktivieren oder sich auf Plattformbibliotheken verlassen, die eine Integer-Überlauf-Bereinigung hatten, können einige Probleme mit harmlosen Integer-Überläufen auftreten, die Abbrüche verursachen. Sie sollten Komponenten mit aktivierter Bereinigung testen, um sicherzustellen, dass harmlose Überläufe auftauchen können.

Um Abbrüche zu finden, die durch Bereinigung in Benutzer-Builds verursacht wurden, suchen Sie nach SIGABRT Abstürzen mit Abbruchmeldungen, die auf einen von UBSan abgefangenen Überlauf hinweisen, wie z. B.:

pid: ###, tid: ###, name: Binder:###  >>> /system/bin/surfaceflinger <<<
signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
Abort message: 'ubsan: sub-overflow'

Der Stack-Trace sollte die Funktion enthalten, die den Abbruch verursacht hat, jedoch sind Überläufe, die in Inline-Funktionen auftreten, möglicherweise nicht im Stack-Trace ersichtlich.

Um die Grundursache einfacher zu ermitteln, aktivieren Sie die Diagnose in der Bibliothek, die den Abbruch auslöst, und versuchen Sie, den Fehler zu reproduzieren. Bei aktivierter Diagnose wird der Prozess nicht abgebrochen , sondern weiter ausgeführt. Kein Abbruch hilft dabei, die Anzahl gutartiger Überläufe in einem bestimmten Ausführungspfad zu maximieren, ohne dass nach dem Beheben jedes Fehlers neu kompiliert werden muss. Die Diagnose erzeugt eine Fehlermeldung, die die Zeilennummer und die Quelldatei enthält, die den Abbruch verursacht haben:

frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp:2188:32: runtime error: unsigned integer overflow: 0 - 1 cannot be represented in type 'size_t' (aka 'unsigned long')

Stellen Sie nach dem Auffinden der problematischen arithmetischen Operation sicher, dass der Überlauf gutartig und beabsichtigt ist (z. B. keine Auswirkungen auf die Sicherheit hat). Sie können den Sanitizer-Abbruch adressieren, indem Sie:

  • Refactoring des Codes, um den Überlauf zu vermeiden ( Beispiel )
  • Überlauf explizit über die __builtin_*_overflow -Funktionen von Clang ( Beispiel )
  • Deaktivieren der Bereinigung in der Funktion durch Angabe des no_sanitize Attributs ( Beispiel )
  • Deaktivieren der Bereinigung einer Funktion oder Quelldatei über eine Blacklist-Datei ( Beispiel )

Sie sollten eine möglichst körnige Lösung verwenden. Beispielsweise sollte bei einer großen Funktion mit vielen arithmetischen Operationen und einer einzelnen überlaufenden Operation die einzelne Operation umgestaltet werden, anstatt die gesamte Funktion auf die schwarze Liste zu setzen.

Häufige Muster, die zu gutartigen Überläufen führen können, sind:

  • Implizite Umwandlungen , bei denen ein vorzeichenloser Überlauf auftritt, bevor sie in einen vorzeichenbehafteten Typ umgewandelt werden ( Beispiel )
  • Löschungen in verknüpften Listen, die den Schleifenindex beim Löschen dekrementieren ( Beispiel )
  • -1 einen vorzeichenlosen Typ zuweisen, anstatt den tatsächlichen Maximalwert anzugeben ( Beispiel )
  • Schleifen, die eine vorzeichenlose Ganzzahl in der Bedingung dekrementieren ( Beispiel , Beispiel )

Es wird empfohlen, dass Entwickler sicherstellen, dass Fälle, in denen das Desinfektionsmittel einen Überlauf erkennt, tatsächlich harmlos sind und keine unbeabsichtigten Nebenwirkungen oder Auswirkungen auf die Sicherheit haben, bevor die Bereinigung deaktiviert wird.

IntSan deaktivieren

Sie können IntSan mit Blacklists oder Funktionsattributen deaktivieren. Deaktivieren Sie sparsam und nur dann, wenn das Umgestalten des Codes anderweitig nicht sinnvoll ist oder wenn es zu einem problematischen Mehraufwand für die Leistung kommt.

Weitere Informationen zum Deaktivieren von IntSan mit Funktionsattributen und zum Formatieren von Blacklist-Dateien finden Sie in der Upstream-Clang-Dokumentation. Das Blacklisting sollte auf das jeweilige Desinfektionsmittel beschränkt werden, indem Abschnittsnamen verwendet werden, die das Ziel-Desinfektionsmittel angeben, um eine Beeinträchtigung anderer Desinfektionsmittel zu vermeiden.

Validierung

Derzeit gibt es keinen CTS-Test speziell für Integer Overflow Sanitization. Stellen Sie stattdessen sicher, dass CTS-Tests mit oder ohne aktiviertem IntSan bestanden werden, um sicherzustellen, dass das Gerät nicht beeinträchtigt wird.