Rust-Fuzzing wird über das libfuzzer-sys
-Crate unterstützt, das Bindungen zur libFuzzer-Fuzzing-Engine von LLVM bietet. Weitere Informationen finden Sie im Repository libfuzzer-sys sowie auf der LLVM libFuzzer-Projektseite.
Das Modul rust_fuzz
erzeugt eine Fuzzer-Binärdatei, die mit dem Fuzzing beginnt, wenn sie ausgeführt wird (ähnlich wie cc_fuzz
-Module). Da der Fuzzer die libFuzzer
-Fuzzing-Engine verwendet, kann er eine Reihe von Argumenten zur Steuerung des Fuzzings entgegennehmen. Diese werden in der libFuzzer-Dokumentation aufgeführt.
rust_fuzz
-Module sind eine Erweiterung von rust_binary
-Modulen und haben daher dieselben Eigenschaften und Überlegungen. Außerdem werden viele der Eigenschaften und Funktionen der cc_fuzz
-Module implementiert.
Beim Erstellen von rust_fuzz
-Modulen wird das Flag --cfg fuzzing
ausgegeben, das verwendet werden kann, um die bedingte Kompilierung von Bibliothekscode zur Verbesserung des Fuzzing zu unterstützen.
Einfachen Rust-Fuzzer schreiben
Sie können ein Fuzzing-Modul in einer Android.bp
-Build-Datei mit diesem Code 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 definiert fuzz_target!(|data: &[u8]| { /* fuzz using data here */ });
den Fuzz-Ziel-Einstiegspunkt, der von der libFuzzer
-Engine aufgerufen wird. Das data
-Argument ist eine Bytefolge, die von der libFuzzer
-Engine bereitgestellt wird, um als Eingabe für das Fuzzing der Zielfunktion manipuliert zu werden.
In diesem Beispiel-Fuzzer wird nur die Länge der Daten geprüft, um zu ermitteln, ob die Funktion heap_oob
aufgerufen werden soll. Der Aufruf führt zu einem Lesen außerhalb des zulässigen Bereichs. libFuzzer
ist ein Coverage-Guided Fuzzer. Daher wird die problematische Länge schnell erreicht, da festgestellt wird, dass die ersten 326 Byte an Daten nicht zu neuen Ausführungspfaden führen.
Sie finden dieses Beispiel im Quellcode unter tools/security/fuzzing/example_rust_fuzzer/.
Ein etwas komplexeres Beispiel für einen anderen Fuzzer (der eine rustlib
-Abhängigkeit im Baum fuzzt) finden Sie unter legacy_blob_fuzzer.
Eine Anleitung zum Schreiben strukturierter Rust-Fuzzer finden Sie im Rust Fuzz-Buch, der offiziellen Dokumentation für das Rust Fuzz-Projekt.