AIDL Fuzzing

Der Fuzzer verhält sich als Client für den Remote-Dienst, indem er ihn über den generierten Stub importiert/aufruft:

Verwenden der C++-API:

#include <fuzzbinder/libbinder_ndk_driver.h>
#include <fuzzer/FuzzedDataProvider.h>

#include <android-base/logging.h>
#include <android/binder_interface_utils.h>

using android::fuzzService;
using ndk::SharedRefBase;

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
    auto binder = ndk::SharedRefBase::make<MyService>(...);

    fuzzService(binder->asBinder().get(), FuzzedDataProvider(data, size));

    return 0;
}

Verwendung der Rust-API:

#![allow(missing_docs)]
#![no_main]
#[macro_use]
extern crate libfuzzer_sys;

use binder::{self, BinderFeatures, Interface};
use binder_random_parcel_rs::fuzz_service;

fuzz_target!(|data: &[u8]| {
    let service = BnTestService::new_binder(MyService, BinderFeatures::default());
    fuzz_service(&mut service.as_binder(), data);
});

Framework zum Fuzzing von AIDL-Diensten

Wie im obigen Beispiel gezeigt, wird fuzzService im Fuzzer aufgerufen und nimmt einen IBinder (Service) und einen dataProvider als Eingabeparameter entgegen. Zunächst wird mithilfe des Datenanbieters ein zufälliges Parcel-Objekt initialisiert, mithilfe des Eingabepakets die Transact-Methode des Remote-Dienstes aufgerufen und schließlich die Antwort in ein Antwortpaket übertragen.

Erstellen und betreiben Sie Fuzzer

Fuzzer werden standardmäßig mit Abdeckung erstellt.

Die folgenden Desinfektionsmittel werden zur Erkennung von Speicherproblemen empfohlen. hwaddress -Desinfektionsmittel laufen nur auf arm Armarchitektur:

SANITIZE_HOST=address SANITIZE_TARGET=hwaddress

Bei der Ausführung mit libFuzzer kann in der Datei Android.bp ein Korpus, also ein Verzeichnis, angegeben werden, und Sie können dieses Verzeichnis an den Fuzzer übergeben. Einige Fuzzer geben in ihrer Android.bp Datei auch ein dictionary: an, und Sie können dieses mit -dict path/to/dict an libFuzzer übergeben. Weitere Optionen finden Sie in der offiziellen libFuzzer-Dokumentation .

Um Fuzzer auf dem Gerät auszuführen, führen Sie adb sync data und dann adb shell data/fuzz/ arch / name / name . Um Fuzzer auf dem Host auszuführen, führen Sie $ANDROID_HOST_OUT/ fuzz / arch / name / name aus.

Das Build-System prüft, ob jeder AOSP-Binderdienst über einen Fuzzer-Eintrag in den Dienst-Fuzzer-Bindungen verfügt. Der Fuzzer-Bindungstest prüft, ob jeder Dienst in service_contexts über einen Fuzzer verfügt. Wenn für einen neuen Dienst kein Fuzzer/Ausnahme gefunden wird, liegt ein Buildfehler vor.

Ein automatischer C++-Dienst-Fuzzer kann geschrieben werden, indem Folgendes hinzugefügt wird (Java- und Rust-Fuzzer werden noch nicht unterstützt):

  • Ein cc_fuzz Eintrag in Android.bp zum Definieren des Fuzzer-Moduls. Das cc_default Modul service_fuzzer_defaults weist Abhängigkeiten auf, die für fuzzService erforderlich sind.
  • Dienstspezifische Abhängigkeiten sollten als Bibliothek oder als Quellen hinzugefügt werden.
  • Eine Hauptdatei, die Ihren Dienst erstellt und fuzzService aufruft

Ausführliche Anweisungen zur Verwendung cc_fuzz finden Sie in der Dokumentation zum Fuzzing mit libFuzzer . Um den Build-Fehler zu beheben, aktualisieren Sie die Bindungen mit den neuen Dienst- und Fuzzer-Namen. Bei Java/Rust-Diensten kann die Fuzzer-Liste leer sein.