UndefinedBehaviorSanitizer

UndefinedBehaviorSanitizer (UBSan) führt eine Instrumentierung während der Kompilierung durch, nach verschiedenen Arten undefinierten Verhaltens suchen. UBSan kann zwar erkennen viele nicht definierte Verhaltensfehler enthält, unterstützt Android:

  • Ausrichtung
  • Boolescher Wert
  • Grenzen
  • Aufzählung
  • Float-Cast-Overflow
  • Durch Gleitkommazahl geteilt durch Null
  • Durch Null dividieren (ganzzahlig)
  • Nicht-Null-Attribut
  • null
  • Zeilenumbruch
  • "return-nonnull-attribute"
  • Basisverschiebung
  • Umschalttaste-Exponent
  • Vorzeichenbehafteter Ganzzahlüberlauf
  • nicht erreichbar
  • Überlauf ohne Vorzeichen
  • Vla-gebunden

unsignierte Ganzzahl-Überlauf, obwohl sie technisch nicht definiert sind. ist im Sanitizer enthalten und wird in vielen Android-Modulen, einschließlich der mediaserver-Komponenten, um latenten Integer-Overflow zu eliminieren Sicherheitslücken.

Implementierung

Im Android-Build-System können Sie UBSan global oder lokal aktivieren. Zum Aktivieren Für UBSan global legen Sie in Android.mk SANITIZE_TARGET fest. Um UBSan zu aktivieren, für Modulebene LOCAL_SANITIZE und geben Sie die nicht definierten Verhaltensweisen an, die Sie in Android.mk suchen. Beispiel:

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_CFLAGS := -std=c11 -Wall -Werror -O0

LOCAL_SRC_FILES:= sanitizer-status.c

LOCAL_MODULE:= sanitizer-status

LOCAL_SANITIZE := alignment bounds null unreachable integer
LOCAL_SANITIZE_DIAG := alignment bounds null unreachable integer

include $(BUILD_EXECUTABLE)

Und die entsprechende Blueprint-Konfiguration (Android.bp):

cc_binary {

    cflags: [
        "-std=c11",
        "-Wall",
        "-Werror",
        "-O0",
    ],

    srcs: ["sanitizer-status.c"],

    name: "sanitizer-status",

    sanitize: {
        misc_undefined: [
            "alignment",
            "bounds",
            "null",
            "unreachable",
            "integer",
        ],
        diag: {
            misc_undefined: [
                "alignment",
                "bounds",
                "null",
                "unreachable",
                "integer",
            ],
        },
    },

}

UBSan-Verknüpfungen

Für Android gibt es auch zwei Tastenkombinationen: integer und default-ub, um mehrere Desinfektionsmittel gleichzeitig zu aktivieren. Ganzzahl aktiviert integer-divide-by-zero, signed-integer-overflow und unsigned-integer-overflow. default-ub aktiviert die Prüfungen mit minimalem Compiler Leistungsprobleme: bool, integer-divide-by-zero, return, returns-nonnull-attribute, shift-exponent, unreachable and vla-bound. Die Die Ganzzahl-Sanitizer-Klasse kann mit SANITIZE_TARGET und LOCAL_SANITIZE verwendet werden. „default-ub“ kann nur mit SANITIZE_TARGET verwendet werden.

Bessere Fehlerberichte

Die UBSan-Standardimplementierung von Android ruft eine angegebene Funktion auf, wenn undefiniertes Verhalten auftritt. Standardmäßig ist diese Funktion Abbrechen. Sie können jedoch Seit Oktober 2016 gibt es bei UBSan auf Android-Geräten eine optionale Laufzeitbibliothek, liefert detailliertere Fehlerberichte, einschließlich der Art des undefinierten Verhaltens sowie Informationen zur Datei und Quellcodezeile. So aktivieren Sie diesen Fehler: Bei Berichten mit ganzzahligen Prüfungen wird einer Android.mk-Datei Folgendes hinzugefügt:

LOCAL_SANITIZE:=integer
LOCAL_SANITIZE_DIAG:=integer

Der Wert LOCAL_SANITIZE aktiviert den Sanitizer während des Builds. LOCAL_SANITIZE_DIAG aktiviert den Diagnosemodus für das angegebene Sanitizer. Es ist LOCAL_SANITIZE und LOCAL_SANITIZE_DIAG können unterschiedliche Werte festgelegt werden, sind nur diese Prüfungen in LOCAL_SANITIZE aktiviert. Ist in der Tabelle LOCAL_SANITIZE, aber in LOCAL_SANITIZE_DIAG angegeben, ist die Prüfung nicht aktiviert und keine Diagnosemeldungen.

Hier ist ein Beispiel für die Informationen, die von der UBSan-Laufzeitbibliothek bereitgestellt werden:

pixel-xl:/ # sanitizer-status ubsan
sanitizer-status/sanitizer-status.c:53:6: runtime error: unsigned integer overflow: 18446744073709551615 + 1 cannot be represented in type 'size_t' (aka 'unsigned long')

Überlaufbereinigung von Ganzzahlen

Unbeabsichtigte Ganzzahlüberläufe können zu Speicherschäden oder Informationen führen Sicherheitslücken in Variablen im Zusammenhang mit Speicherzugriffen oder Arbeitsspeicherzuweisungen. Um dem entgegenzuwirken, haben wir UndefinedBehaviorSanitizer (UBSan) Integer-Überlauf-Sanitizer mit und ohne Vorzeichen in härten das Media-Framework in Android 7.0. In Android 9 maximiert UBSan, um mehr Komponenten abzudecken, und eine verbesserte Build-Systemunterstützung dafür.

Dies dient dazu, Überprüfungen der Arithmetik hinzuzufügen. Bedienungsanleitungen, die möglicherweise Überlauf: Ein Prozess wird im Falle eines Überlaufs sicher abgebrochen. Diese Sanitizer können eine ganze Klasse von Speicherbeschädigungen mindern. und Schwachstellen bei der Offenlegung von Informationen, deren Ursache eine Ganzzahl ist wie die ursprüngliche Stagefright-Sicherheitslücke.

Beispiele und Quelle

Integer Overflow Sanitization (IntSan) wird vom Compiler bereitgestellt und fügt Instrumentierung in das Binärprogramm während der Kompilierungszeit zur Erkennung der Arithmetik Überlauf. Es ist standardmäßig in verschiedenen Komponenten im Plattform, z. B. /platform/external/libnl/Android.bp

Implementierung

IntSan verwendet Überlauf-Sanitizers mit Vorzeichen und ohne Vorzeichen von UBSan. Dieses Die Risikominderung ist auf Modulebene aktiviert. Es trägt dazu bei, dass wichtige Komponenten von Android sicher und sollte nicht deaktiviert werden.

Wir empfehlen Ihnen dringend, die Überlaufbereinigung für Ganzzahlen für zusätzliche Komponenten. Idealerweise bieten wir privilegierten nativen Code oder nativen Code, der parst die Eingaben nicht vertrauenswürdiger Nutzer. Es ist ein geringer Leistungsaufwand mit dem Desinfektionsmittel, das von der Nutzung des Codes und der arithmetische Operationen. Erwarten Sie einen geringen Aufwandsprozentsatz und testen Sie, ob die Leistung ist ein Problem.

IntSan in Makefiles unterstützen

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_BLOCKLIST := modulename_BLOCKLIST.txt
  • LOCAL_SANITIZE enthält eine durch Kommas getrennte Liste von Desinfektionsmitteln. Dabei handelt es sich bei integer_overflow um eine Reihe von vorkonfigurierten Optionen für die einzelnen signierten und vorzeichenlosen Ganzzahlüberlauf-Sanitizers mit einem Standard BLOCKLISTE
  • LOCAL_SANITIZE_DIAG aktiviert den Diagnosemodus für das Desinfektionsmittel. Diagnosemodus nur während des Tests verwenden, da dies nicht der Fall ist bei Überlauf abbrechen, wodurch der Sicherheitsvorteil der und Risikominderung. Weitere Informationen finden Sie im Hilfeartikel Fehlerbehebung. .
  • Mit LOCAL_SANITIZE_BLOCKLIST können Sie eine BLOCKLIST-Liste angeben um zu verhindern, dass Funktionen und Quelldateien bereinigt werden. Weitere Informationen finden Sie unter Weitere Informationen zur Fehlerbehebung Details.

Wenn du eine detailliertere Kontrolle haben möchtest, aktiviere die Desinfektionsmittel einzeln über eines oder beide Flags verwenden:

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

IntSan in Blueprint-Dateien unterstützen

Um Ganzzahlüberlauf-Bereinigung in einer Blueprint-Datei zu aktivieren, z. B. /platform/external/libnl/Android.bp, Hinzufügen:

   sanitize: {
          integer_overflow: true,
          diag: {
              integer_overflow: true,
          },
          BLOCKLIST: "modulename_BLOCKLIST.txt",
       },

Wie bei Erstellungsdateien ist das Attribut integer_overflow ein vorkonfiguriertes Satz von Optionen für den Überlauf von einzelnen vorzeichenbehafteten und vorzeichenlosen Ganzzahlen Desinfektionsmittel mit einem Standard BLOCKLISTE

Mit den diag-Attributen wird der Diagnosemodus für das Desinfektionsmittel. Diagnosemodus nur während Tests verwenden. Im Diagnosemodus bei Überlauf abbrechen, was den Sicherheitsvorteil der in Nutzer-Builds abschwächen. Weitere Informationen finden Sie unter Fehlerbehebung.

Mit dem Attribut BLOCKLIST kann eine BLOCKLIST-Datei angegeben werden mit der Entwickler verhindern können, dass Funktionen und Quelldateien gesäubert. Weitere Informationen finden Sie unter Fehlerbehebung für weitere Details.

So aktivieren Sie die Desinfektionsmittel einzeln:

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

Fehlerbehebung

Wenn Sie Integer-Overflow-Bereinigung in neuen Komponenten aktivieren oder Plattformbibliotheken, bei denen eine Integer-Overflow-Bereinigung erfolgt ist, Probleme mit harmlosen ganzzahligen Überläufen, die Abbrüche verursachen. Sie sollten Komponenten mit aktivierter Bereinigung, damit harmlose Überläufe angezeigt werden können.

Um herauszufinden, ob Abbrüche durch Bereinigung in Nutzer-Builds verursacht werden, suchen Sie nach SIGABRT stürzt mit Abbruchmeldungen ab, die auf einen Überlauf hinweisen von UBSan, wie zum Beispiel:

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

Der Stacktrace sollte jedoch die Funktion enthalten, die den Abbruch verursacht: Überläufe, die bei Inline-Funktionen auftreten, sind im Stacktrace möglicherweise nicht ersichtlich.

Wenn Sie die Ursache leichter ermitteln möchten, aktivieren Sie die Diagnosefunktion in der Bibliothek den Abbruch auslösen und versuchen, den Fehler zu reproduzieren. Mit aktiviert ist, wird der Vorgang nicht abgebrochen, sondern stattdessen weiterlaufen lassen. Ohne Abtreibung lässt sich die Anzahl der gutartigen Überläufe in einer ohne einen Fehler neu kompilieren zu müssen. Das Diagnosetool gibt eine Fehlermeldung aus, die die Zeilennummer und die Quelle enthält Datei, die den Abbruch verursacht:

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')

Sobald die problematische arithmetische Operation gefunden wurde, stellen Sie sicher, dass der Überlauf sind harmlos und beabsichtigt (hat z.B. keine Auswirkungen auf die Sicherheit). Sie können die Probleme Desinfektionsmittel abbrechen durch:

  • Code refaktorieren, um Überlauf zu vermeiden (Beispiel)
  • Expliziter Überlauf über die Clang-Funktion __builtin_*_overflow. Funktionen (Beispiel)
  • Deaktivieren der Bereinigung in der Funktion durch Angabe des Attributs no_sanitize (Beispiel)
  • Bereinigung einer Funktion oder Quelldatei über eine BLOCKLIST-Datei deaktivieren (Beispiel)

Verwenden Sie eine möglichst detaillierte Lösung. Eine große -Funktion mit vielen arithmetischen Operationen und einer einzelnen Überlaufoperation sollte nur der einzelne Vorgang refaktoriert werden und nicht die gesamte Funktion. Auf der Sperrliste.

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

  • Implizit Umwandlungen, bei denen ein unsignierter Überlauf auftritt, bevor in einen signierten Typ umgewandelt wird (Beispiel)
  • Löschungen von verknüpften Listen, wodurch der Schleifenindex beim Löschen verringert wird (Beispiel)
  • -1 einen vorzeichenlosen Typ zuweisen, anstatt den tatsächlichen Maximalwert anzugeben (Beispiel)
  • Schleifen, die eine vorzeichenlose Ganzzahl in der Bedingung verringern (Beispiel, Beispiel)

Entwickler sollten darauf achten, dass in Fällen, in denen das dass es tatsächlich harmlos ist und keine unbeabsichtigten Nebenwirkungen oder Sicherheit enthält. Auswirkungen haben, bevor die Bereinigung deaktiviert wird.

IntSan deaktivieren

Sie können IntSan mit BLOCKLISTs oder Funktionsattributen deaktivieren. Nur sparsam deaktivieren und nur dann, wenn eine Refaktorierung des Codes ansonsten unangemessen ist und problematischen Leistungsaufwand.

Weitere Informationen zum Deaktivieren von IntSan finden Sie in der Upstream-Clang-Dokumentation mit -Funktion Attribute und BLOCKLIST-Datei und Formatierung. BLOCKLISTing sollte auf das jeweilige Desinfektionsmittel beschränkt werden, indem unter Verwendung von Abschnittsnamen, in denen der Ziel-Sanitizer angegeben wird, um Beeinträchtigungen anderer Desinfektionsmittel.

Zertifizierungsstufe

Derzeit gibt es keinen CTS-Test speziell für die Integer-Überlaufbereinigung. Stellen Sie stattdessen sicher, dass die CTS-Tests mit oder ohne aktiviertes IntSan zur Verifizierung bestanden werden. dass es keine Auswirkungen auf das Gerät hat.

Bounds-Bereinigung

BoundsSanitizer (BoundSan) fügt Binärdateien eine Instrumentierung hinzu, um Grenzen einzufügen überprüft Array-Zugriffe. Diese Prüfungen werden hinzugefügt, wenn der Compiler Beweisen beim Kompilieren, dass der Zugriff sicher ist und ob die Größe des Arrays zur Laufzeit bekannt, damit er verglichen werden kann. Android 10 stellt BoundSan in Bluetooth und Codecs BoundSan wird vom Compiler bereitgestellt und durch in verschiedenen Komponenten der Plattform.

Implementierung

BoundSan verwendet UBSans Bounds Sanitizer. Diese Entschärfung wird für jedes Modul aktiviert. Es hilft zum Schutz wichtiger Komponenten von Android. Sie sollten nicht deaktiviert werden.

Wir empfehlen Ihnen dringend, BoundSan für zusätzliche Komponenten zu aktivieren. Idealerweise eignen sich privilegierter nativer Code oder komplexer nativer Code, der parst. Eingabe eines nicht vertrauenswürdigen Nutzers. Der Leistungsaufwand, der mit der Aktivierung von BoundSan verbunden ist hängt von der Anzahl der Arrayzugriffe ab, die nicht als sicher bewiesen werden können. Sie erwarten einen geringen Prozentsatz des Aufwands im Durchschnitt und testen, ob die Leistung ein Problem darstellt.

BoundSan in Blueprint-Dateien aktivieren

BoundSan kann in Blueprint-Dateien aktiviert werden, indem du "bounds" hinzufügst zur misc_undefined sanitize-Eigenschaft für Binärdateien und Bibliothek Module:

    sanitize: {
       misc_undefined: ["bounds"],
       diag: {
          misc_undefined: ["bounds"],
       },
       BLOCKLIST: "modulename_BLOCKLIST.txt",
Diag

Das Attribut diag aktiviert den Diagnosemodus für die Desinfektionsmittel. Diagnosemodus nur während Tests verwenden. Diagnosemodus wird nicht abgebrochen an Überlauf, was den Sicherheitsvorteil der Risikominderung zunichte macht und eine höhere Leistung und wird daher für Produktions-Builds nicht empfohlen.

BLOCKLISTE

Das Attribut BLOCKLIST ermöglicht die Angabe einer BLOCKLIST-Datei. Datei, mit der Entwickler verhindern können, dass Funktionen und Quelldateien gesäubert. Verwenden Sie diese Property nur, wenn die Leistung wichtig ist und die Dateien/Funktionen einen wesentlichen Beitrag leisten. Diese Dateien/Funktionen manuell prüfen um sicherzustellen, dass Array-Zugriffe sicher sind. Weitere Informationen finden Sie unter Fehlerbehebung. Details.

BoundSan in Makefiles aktivieren

BoundSan kann in Makefiles aktiviert werden, indem du "bounds" hinzufügst in die Variable LOCAL_SANITIZE für Binär- und Bibliotheksmodule:

    LOCAL_SANITIZE := bounds
    # Optional features
    LOCAL_SANITIZE_DIAG := bounds
    LOCAL_SANITIZE_BLOCKLIST := modulename_BLOCKLIST.txt

LOCAL_SANITIZE akzeptiert eine Liste von Desinfektionsmitteln, getrennt durch ein Komma.

LOCAL_SANITIZE_DIAG aktiviert den Diagnosemodus. Diagnose verwenden Testmodus verwenden. Der Diagnosemodus bricht bei Überläufen nicht ab, negiert den Sicherheitsvorteil der Risikominderung und führt zu einer höheren und wird daher nicht für Produktions-Builds empfohlen.

LOCAL_SANITIZE_BLOCKLIST ermöglicht die Angabe einer BLOCKLIST-Liste. Datei, mit der Entwickler verhindern können, dass Funktionen und Quelldateien gesäubert. Verwenden Sie diese Property nur, wenn die Leistung wichtig ist und die Dateien/Funktionen einen wesentlichen Beitrag leisten. Diese Dateien/Funktionen manuell prüfen um sicherzustellen, dass Array-Zugriffe sicher sind. Weitere Informationen finden Sie unter Fehlerbehebung. Details.

BoundSan deaktivieren

Sie können BoundSan in Funktionen und Quelldateien mit BLOCKLISTs oder Funktionsattributen verwendet werden. Es empfiehlt sich, BoundSan aktiviert zu lassen. Deaktivieren Sie es also nur, wenn dass die Funktion oder Datei einen großen Leistungsaufwand verursacht. wurde manuell überprüft.

Weitere Informationen zum Deaktivieren von BoundSan mit der Funktion Attribute und BLOCKLIST-Datei Informationen zur Formatierung finden Sie in der Dokumentation zu Clang LLVM. Legen Sie den Umfang der BLOCKLISTE an das jeweilige Desinfektionsmittel durch die Verwendung von Abschnittsnamen, in denen die Ziel-Desinfektionsmittel verwenden, um Auswirkungen auf andere Desinfektionsmittel zu vermeiden.

Zertifizierungsstufe

Es gibt keinen speziellen CTS-Test für BoundSan. Stellen Sie stattdessen sicher, dass CTS die Tests mit oder ohne aktiviertem BoundSans durchgehen, um zu prüfen, ob dies auf dem Gerät.

Fehlerbehebung

Testen Sie Komponenten gründlich, nachdem Sie BoundSan aktiviert haben, um sicherzustellen, dass alle zuvor unerkannte externe Zugriffe behandelt werden.

BoundSan-Fehler können leicht identifiziert werden, da sie Folgendes umfassen: Tombstone-Abbruchnachricht:

    pid: ###, tid: ###, name: Binder:###  >>> /system/bin/foobar <<<
    signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
    Abort message: 'ubsan: out-of-bounds'

Im Diagnosemodus werden die Quelldatei, die Zeilennummer und der Index werden an logcat ausgegeben. Standardmäßig werden in diesem Modus keine Eine Abbruchnachricht ausgeben. Prüfen Sie logcat, um zu prüfen, ob es irgendwelche Fehler.

    external/foo/bar.c:293:13: runtime error: index -1 out of bounds for type 'int [24]'