模糊模塊

Rust 模糊測試透過libfuzzer-sys crate 支持,它提供了到 LLVM 的 libFuzzer 模糊測試引擎的綁定。有關更多信息,請參閱libfuzzer-sys存儲庫以及LLVM libFuzzer 項目頁面

rust_fuzz模組產生一個模糊器二進位文件,該二進位檔案在運行時開始模糊測試(類似於cc_fuzz模組)。由於模糊器利用libFuzzer模糊測試引擎,因此它可以採用多個參數來控制模糊測試。 libFuzzer 文件中列舉了這些內容。

rust_fuzz模組是rust_binary模組的擴展,因此具有相同的屬性和注意事項。此外,它們還實現了許多與cc_fuzz模組相同的屬性和功能。

建置rust_fuzz模組時,會發出--cfg fuzzing標誌,可用來支援函式庫程式碼的條件編譯以改善模糊測試。

寫一個基本的 Rust 模糊器

您可以使用以下程式碼在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檔案包含一個簡單的模糊器:

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();
    }
});

這裡fuzz_target!(|data: &[u8]| { /* fuzz using data here */ });定義libFuzzer引擎呼叫的模糊目標入口點。 data參數是libFuzzer引擎提供的位元組序列,可作為輸入進行操作以模糊目標函數。

在此範例模糊器中,僅檢查資料的長度以確定是否呼叫heap_oob函數,呼叫函數會導致越界讀取。 libFuzzer是一個覆蓋引導的模糊器,因此它可以快速收斂到有問題的長度,因為它確定前 326 B 資料不會導致新的執行路徑。

在樹中找到此範例,位於tools/security/fuzzing/example_rust_fuzzer/ 。若要查看樹內另一個模糊器(模糊rustlib依賴項)的稍微複雜的範例,請參閱legacy_blob_fuzzer

有關如何編寫結構感知 Rust 模糊器的指南,請參閱Rust Fuzz 書,這是 Rust Fuzz 專案的官方文件。