模糊模組

libfuzzer-sys Crate 支援 Rust 模糊測試,這個 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/。如要查看較複雜的例子,請參閱legacy_blob_fuzzer,瞭解如何在樹狀結構中使用另一個模糊器 (用於模糊處理 rustlib 依附元件)。

如需如何編寫可感知結構的 Rust 模糊工具指南,請參閱 Rust Fuzz 書籍,這是 Rust Fuzz 專案的官方說明文件。