Scudo

Scudo ist ein dynamischer Speicherzuordner oder Heap - Zuordner im Benutzermodus , der so konzipiert ist, dass er gegen Heap-bezogene Schwachstellen (wie z. Es stellt die C-Standardprimitiven für die Zuweisung und Aufhebung der Zuweisung (wie malloc und free) sowie die C++-Primitiven (wie new und delete) bereit.

Scudo ist eher eine Abschwächung als ein vollwertiger Speicherfehlerdetektor wie AddressSanitizer (ASan) .

Ab der Version von Android 11 wird scudo für den gesamten nativen Code verwendet (außer auf Geräten mit wenig Arbeitsspeicher, auf denen immer noch jemalloc verwendet wird). Zur Laufzeit werden alle nativen Heap-Zuweisungen und -Freigaben von Scudo für alle ausführbaren Dateien und ihre Bibliotheksabhängigkeiten gewartet, und der Prozess wird abgebrochen, wenn eine Beschädigung oder verdächtiges Verhalten im Heap festgestellt wird.

In Android 10 musste Scudo auf Binärbasis aktiviert werden, indem die LOCAL_SANITIZE := scudo in der .mk-Datei oder die sanitize sanitize: { scudo: true, } in der .bp-Datei festgelegt wurde.

Scudo ist Open Source und Teil des Compiler-RT-Projekts von LLVM. Die Dokumentation ist unter https://llvm.org/docs/ScudoHardenedAllocator.html verfügbar. Die Scudo-Laufzeitumgebung wird als Teil der Android-Toolchain ausgeliefert, und Unterstützung wurde zu Soong und Make hinzugefügt, um eine einfache Aktivierung des Allokators in einer Binärdatei zu ermöglichen.

Mithilfe der unten beschriebenen Optionen können Sie zusätzliche Schutzmaßnahmen innerhalb der Zuweisung aktivieren oder deaktivieren.

Anpassung

Einige Parameter des Zuordners können auf prozessspezifischer Basis auf verschiedene Arten definiert werden:

  • Statisch: Definieren Sie eine __scudo_default_options Funktion im Programm, die die zu analysierende Optionszeichenfolge zurückgibt. Diese Funktion muss den folgenden Prototyp haben: extern "C" const char *__scudo_default_options() .
  • Dynamisch: Verwenden Sie die Umgebungsvariable SCUDO_OPTIONS , die die zu analysierende Optionszeichenfolge enthält. Auf diese Weise definierte Optionen überschreiben alle Definitionen, die durch __scudo_default_options vorgenommen wurden.

Die folgenden Optionen sind verfügbar.

Möglichkeit 64-Bit-Standard 32-Bit-Standard Beschreibung
QuarantineSizeKb 256 64 Die Größe (in KB) der Quarantäne, die verwendet wird, um die tatsächliche Freigabe von Chunks zu verzögern. Ein niedrigerer Wert kann die Speicherauslastung verringern, aber die Wirksamkeit der Schadensbegrenzung verringern; ein negativer Wert fällt auf die Standardwerte zurück. Wenn Sie sowohl this als ThreadLocalQuarantineSizeKb auf Null setzen, wird die Quarantäne vollständig deaktiviert.
QuarantineChunksUpToSize 2048 512 Die Größe (in Byte), bis zu der Chunks unter Quarantäne gestellt werden können.
ThreadLocalQuarantineSizeKb 64 16 Die Größe (in KB) des Caches pro Thread, der zum Auslagern der globalen Quarantäne verwendet wird. Ein niedrigerer Wert kann die Speicherauslastung verringern, aber Konflikte in der globalen Quarantäne erhöhen. Wenn Sie sowohl dies als auch QuarantineSizeKb auf Null setzen, wird die Quarantäne vollständig deaktiviert.
DeallocationTypeMismatch false false Aktiviert die Fehlerberichterstattung bei malloc/delete, new/free, new/delete[]
DeleteSizeMismatch true true Aktiviert die Fehlerberichterstattung bei Diskrepanzen zwischen den Größen von new und delete.
ZeroContents false false Aktiviert Zero-Chunk-Inhalte bei Zuweisung und Freigabe.
allocator_may_return_null false false Gibt an, dass die Zuweisung null zurückgeben kann, wenn ein behebbarer Fehler auftritt, anstatt den Prozess zu beenden.
hard_rss_limit_mb 0 0 Wenn der RSS des Prozesses diese Grenze erreicht, wird der Prozess beendet.
soft_rss_limit_mb 0 0 Wenn der RSS des Prozesses dieses Limit erreicht, schlagen weitere Zuordnungen fehl oder geben null zurück (abhängig vom Wert von allocator_may_return_null ), bis der RSS wieder nach unten geht, um neue Zuordnungen zu ermöglichen.
allocator_release_to_os_interval_ms N / A 5000 Betrifft nur eine 64-Bit-Zuweisung. Wenn festgelegt, wird versucht, ungenutzten Speicher für das Betriebssystem freizugeben, jedoch nicht öfter als dieses Intervall (in Millisekunden). Wenn der Wert negativ ist, wird kein Arbeitsspeicher für das Betriebssystem freigegeben.
abort_on_error true true Wenn gesetzt, ruft das Tool nach dem Drucken der Fehlermeldung abort() anstelle von _exit() auf.

Validierung

Derzeit gibt es keine CTS-Tests speziell für Scudo. Stellen Sie stattdessen sicher, dass CTS-Tests mit oder ohne aktiviertem Scudo für eine bestimmte Binärdatei bestanden werden, um sicherzustellen, dass das Gerät nicht beeinträchtigt wird.

Fehlerbehebung

Wenn ein nicht behebbares Problem erkannt wird, zeigt der Zuordner eine Fehlermeldung für den Standardfehlerdeskriptor an und beendet dann den Prozess. Stack-Traces, die zum Abbruch führen, werden im Systemlog hinzugefügt. Die Ausgabe beginnt normalerweise mit Scudo ERROR: gefolgt von einer kurzen Zusammenfassung des Problems zusammen mit Hinweisen.

Hier eine Auflistung der aktuellen Fehlermeldungen und deren möglichen Ursachen:

  • corrupted chunk header : Die Prüfsummenüberprüfung des Chunk-Headers ist fehlgeschlagen. Dies liegt wahrscheinlich an einem von zwei Dingen: Der Header wurde (teilweise oder vollständig) überschrieben, oder der an die Funktion übergebene Zeiger ist kein Chunk.
  • race on chunk header : Zwei verschiedene Threads versuchen gleichzeitig, denselben Header zu manipulieren. Dies ist normalerweise symptomatisch für eine Race-Condition oder einen allgemeinen Mangel an Sperren, wenn Operationen auf diesem Chunk ausgeführt werden.
  • invalid chunk state : Der Chunk befindet sich nicht im erwarteten Zustand für einen bestimmten Vorgang, z. B. wird er nicht zugewiesen, wenn versucht wird, ihn freizugeben, oder er wird nicht unter Quarantäne gestellt, wenn versucht wird, ihn zu recyceln. Ein Double Free ist der typische Grund für diesen Fehler.
  • misaligned pointer : Grundlegende Ausrichtungsanforderungen werden streng erzwungen: 8 Byte auf 32-Bit-Plattformen und 16 Byte auf 64-Bit-Plattformen. Wenn ein an unsere Funktionen übergebener Zeiger nicht zu diesen passt, ist der an eine der Funktionen übergebene Zeiger nicht ausgerichtet.
  • allocation type mismatch überein : Wenn diese Option aktiviert ist, muss eine Aufhebungsfunktion, die für einen Chunk aufgerufen wird, mit dem Funktionstyp übereinstimmen, der aufgerufen wurde, um ihn zuzuweisen. Diese Art von Diskrepanz kann zu Sicherheitsproblemen führen.
  • invalid sized delete : Wenn der C++14-Operator zum Löschen der Größe verwendet wird und die optionale Prüfung aktiviert ist, gibt es eine Diskrepanz zwischen der Größe, die beim Aufheben der Zuweisung eines Blocks übergeben wurde, und der Größe, die beim Zuweisen angefordert wurde. Dies ist normalerweise ein Compilerproblem oder eine Typverwirrung bei dem Objekt, dessen Zuordnung aufgehoben wird.
  • RSS limit exhausted : Das optional angegebene maximale RSS wurde überschritten.

Wenn Sie einen Absturz im Betriebssystem selbst debuggen, können Sie einen HWAAn OS-Build verwenden. Wenn Sie einen Absturz in einer App debuggen, können Sie auch einen HWAAn-App-Build verwenden.