通過libfuzzer-sys
crate 支持 Rust 模糊測試,它提供與 LLVM 的 libFuzzer 模糊測試引擎的綁定。有關更多信息,請參閱libfuzzer-sys存儲庫以及LLVM libFuzzer 項目頁面。
rust_fuzz
模塊生成一個模糊器二進製文件,它在運行時開始模糊測試(類似於cc_fuzz
模塊)。由於 fuzzer 利用libFuzzer
引擎,它可以使用許多參數來控制 fuzzing。這些都在libFuzzer 文檔中列出。
rust_fuzz
模塊是rust_binary
模塊的擴展,因此具有相同的屬性和注意事項。此外,它們實現了許多與cc_fuzz
模塊相同的屬性和功能。
編寫一個基本的 Rust fuzzer
您可以使用以下代碼在Android.bp
構建文件中定義模糊模塊:
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",
}
fuzzer.rs
文件包含一個簡單的 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();
}
});
Here fuzz_target!(|data: &[u8]| { /* fuzz using data here */ });
定義libFuzzer
引擎調用的 fuzz-target 入口點。 data
參數是libFuzzer
引擎提供的字節序列,可作為輸入來對目標函數進行模糊測試。
在此示例模糊器中,僅檢查數據的長度以確定是否調用heap_oob
函數,調用該函數會導致越界讀取。 libFuzzer
是一個覆蓋引導的模糊器,因此它可以快速收斂到有問題的長度,因為它確定前 326 B 的數據不會導致新的執行路徑。
在tools/security/fuzzing/example_rust_fuzzer/找到這個示例,在樹中。要查看樹中另一個模糊器( rustlib
依賴項)的稍微複雜的示例,請參閱legacy_blob_fuzzer 。
有關如何編寫結構感知 Rust fuzzer 的指導,請參閱Rust Fuzz 書,這是 Rust Fuzz 項目的官方文檔。