Fuzz-Module

Rust-Fuzzing wird durch die libfuzzer-sys Kiste unterstützt, die Bindungen an die libFuzzer-Fuzzing-Engine von LLVM bereitstellt. Weitere Informationen finden Sie im libfuzzer-sys- Repository sowie auf der LLVM-libFuzzer-Projektseite .

Das rust_fuzz Modul erzeugt eine Fuzzer-Binärdatei, die bei der Ausführung mit dem Fuzzing beginnt (ähnlich den cc_fuzz Modulen). Da der Fuzzer die Fuzzing-Engine libFuzzer nutzt, kann er eine Reihe von Argumenten zur Steuerung des Fuzzings benötigen. Diese sind in der libFuzzer-Dokumentation aufgeführt.

rust_fuzz -Module sind eine Erweiterung der rust_binary Module und haben als solche dieselben Eigenschaften und Überlegungen. Darüber hinaus implementieren sie viele der gleichen Eigenschaften und Funktionen wie die cc_fuzz Module.

Beim Erstellen von rust_fuzz Modulen wird das --cfg fuzzing ausgegeben, das zur Unterstützung der bedingten Kompilierung von Bibliothekscode zur Verbesserung des Fuzzing verwendet werden kann.

Schreiben Sie einen einfachen Rust-Fuzzer

Mit diesem Code können Sie ein Fuzz-Modul in einer Android.bp Build-Datei definieren:

rust_fuzz {
    name: "example_rust_fuzzer",
    srcs: ["fuzzer.rs"],

    // Config for running the target on fuzzing infrastructure can be set under
    // fuzz_config. This shares the same properties as cc_fuzz's fuzz_config.
    fuzz_config: {
        fuzz_on_haiku_device: true,
        fuzz_on_haiku_host: false,
    },

    // Path to a corpus of sample inputs, optional. See https://llvm.org/docs/LibFuzzer.html#corpus
    corpus: ["testdata/*"],

    // Path to a dictionary of sample byte sequences, optional. See https://llvm.org/docs/LibFuzzer.html#dictionaries
    dictionary: "example_rust_fuzzer.dict",
}

Die Datei fuzzer.rs enthält einen einfachen Fuzzer:

fn heap_oob() {
    let xs = vec![0, 1, 2, 3];
    let val = unsafe { *xs.as_ptr().offset(4) };
    println!("Out-of-bounds heap value: {}", val);
}

fuzz_target!(|data: &[u8]| {
    let magic_number = 327;
    if data.len() == magic_number {
        heap_oob();
    }
});

Hier fuzz_target!(|data: &[u8]| { /* fuzz using data here */ }); Definiert den Fuzz-Target-Einstiegspunkt, der von der libFuzzer -Engine aufgerufen wird. Das data ist eine Folge von Bytes, die von der libFuzzer Engine bereitgestellt werden und als Eingabe zum Fuzzen der Zielfunktion manipuliert werden können.

In diesem Beispiel-Fuzzer wird nur die Länge der Daten überprüft, um zu bestimmen, ob die Funktion heap_oob aufgerufen werden soll, deren Aufruf zu einem Lesevorgang außerhalb der Grenzen führt. libFuzzer ist ein Coverage-gesteuerter Fuzzer, der sich schnell an die problematische Länge annähert, da er feststellt, dass die ersten 326 B an Daten nicht zu neuen Ausführungspfaden führen.

Suchen Sie dieses Beispiel im Baum unter tools/security/fuzzing/example_rust_fuzzer/ . Um ein etwas komplexeres Beispiel eines anderen Fuzzers (der eine rustlib Abhängigkeit fuzzt) im Baum anzuzeigen, sehen Sie sich den Legacy_blob_fuzzer an.

Eine Anleitung zum Schreiben strukturbewusster Rust-Fuzzer finden Sie im Rust Fuzz-Buch , der offiziellen Dokumentation zum Rust Fuzz-Projekt.