Fuzz modülleri

Rust fuzzing, LLVM'in libFuzzer fuzzing motoruna bağlama sağlayan libfuzzer-sys paketi aracılığıyla desteklenir. Daha fazla bilgi için libfuzzer-sys deposuna ve LLVM libFuzzer proje sayfasına göz atın.

rust_fuzz modülü, çalıştırıldığında fuzzing yapmaya başlayan bir fuzzer ikili dosyası oluşturur (cc_fuzz modüllerine benzer). Fuzzer, libFuzzer fuzzing motorunu kullandığından, fuzzing'i kontrol etmek için birkaç bağımsız değişken gerekebilir. Bunlar libFuzzer dokümanlarında belirtilmiştir.

rust_fuzz modüller, rust_binary modülün bir uzantısıdır ve bu nedenle aynı özellikleri ve dikkat edilmesi gereken noktaları paylaşır. Ayrıca, cc_fuzz modülleriyle aynı özellik ve işlevlerin çoğunu uygularlar.

rust_fuzz modülleri oluşturulurken --cfg fuzzing işareti gönderilir. Bu işaret, bulanık testi iyileştirmek için kitaplık kodunun koşullu derlemesini desteklemek amacıyla kullanılabilir.

Temel bir Rust fuzzer yaz

Aşağıdaki kodu kullanarak bir Android.bp derleme dosyasında fuzz modülü tanımlayabilirsiniz:

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 dosyası basit bir fuzzer içeriyor:

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

Burada fuzz_target!(|data: &[u8]| { /* fuzz using data here */ });, libFuzzer motoru tarafından çağrılan bulanıklık hedefi giriş noktasını tanımlar. data bağımsız değişkeni, hedeflenen işlevi bulanıklaştırmak için giriş olarak manipüle edilmek üzere libFuzzer motoru tarafından sağlanan bir bayt dizisidir.

Bu örnekte, heap_oob işlevinin çağrılıp çağrılmayacağını belirlemek için yalnızca verilerin uzunluğu kontrol edilir. Bu işlevin çağrılması, sınır dışı okumayla sonuçlanır. libFuzzer, kapsama odaklı bir fuzzer olduğundan, ilk 326 B verinin yeni yürütme yollarına yol açmadığını belirlediği için sorunlu uzunluğa hızla ulaşır.

Bu örneği (ağaç içi) tools/security/fuzzing/example_rust_fuzzer/ adresinde bulabilirsiniz. Ağdaki başka bir fuzzer'ın (rustlib bağımlılıklarını bulanıklaştıran) biraz daha karmaşık bir örneğini görmek için legacy_blob_fuzzer dosyasını inceleyin.

Yapıya duyarlı Rust fuzzer yazma konusunda yardım almak için Rust Fuzz projesinin resmi belgeleri olan Rust Fuzz kitabını inceleyin.