Moduły Fuzza

Fuzzowanie rdzy jest obsługiwane przez skrzynkę libfuzzer-sys , która zapewnia powiązania z silnikiem fuzzera libFuzzer LLVM. Więcej informacji można znaleźć w repozytorium libfuzzer-sys oraz na stronie projektu LLVM libFuzzer .

Moduł rust_fuzz tworzy plik binarny fuzzera, który zaczyna fuzzować po uruchomieniu (podobnie jak moduły cc_fuzz ). Ponieważ fuzzer wykorzystuje silnik fuzzera libFuzzer , kontrolowanie fuzzera może wymagać wielu argumentów. Są one wyliczone w dokumentacji libFuzzer .

Moduły rust_fuzz są rozszerzeniem modułów rust_binary i jako takie mają te same właściwości i uwagi. Dodatkowo implementują wiele takich samych właściwości i funkcjonalności, jak moduły cc_fuzz .

Podczas budowania modułów rust_fuzz emitowana jest flaga --cfg fuzzing , której można użyć do obsługi warunkowej kompilacji kodu biblioteki w celu poprawy fuzzowania.

Napisz podstawowy fuzzer Rusta

Możesz zdefiniować moduł fuzz w pliku kompilacji Android.bp za pomocą tego kodu:

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",
}

Plik fuzzer.rs zawiera prosty 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();
    }
});

Tutaj fuzz_target!(|data: &[u8]| { /* fuzz using data here */ }); definiuje punkt wejścia celu fuzz wywoływany przez silnik libFuzzer . Argument data to sekwencja bajtów dostarczana przez silnik libFuzzer , którymi można manipulować jako dane wejściowe w celu fuzowania docelowej funkcji.

W tym przykładzie fuzzera sprawdzana jest tylko długość danych, aby określić, czy wywołać funkcję heap_oob , której wywołanie skutkuje odczytem poza dopuszczalnym zakresem. libFuzzer to fuzzer sterowany zasięgiem, więc szybko osiąga problematyczną długość, ponieważ ustala, że ​​pierwsze 326 B danych nie skutkuje nowymi ścieżkami wykonania.

Znajdź ten przykład w drzewie pod adresem Tools/security/fuzzing/example_rust_fuzzer/ . Aby zobaczyć nieco bardziej złożony przykład innego fuzzera (który rozmywa zależność rustlib ) w drzewie, zobacz dziedzictwo_blob_fuzzer .

Wskazówki dotyczące pisania fuzzerów Rust świadomych struktury można znaleźć w książce Rust Fuzz , oficjalnej dokumentacji projektu Rust Fuzz.