Módulos fuzz

La fuzzing de óxido se admite a través de la caja libfuzzer-sys , que proporciona enlaces al motor de fuzzing libFuzzer de LLVM. Para obtener más información, consulte el repositorio libfuzzer-sys y la página del proyecto LLVM libFuzzer .

El módulo rust_fuzz produce un binario fuzzer que comienza a difuminarse cuando se ejecuta (similar a los módulos cc_fuzz ). Como el fuzzer aprovecha el motor de fuzzer libFuzzer , pueden ser necesarios varios argumentos para controlar el fuzzer. Estos se enumeran en la documentación de libFuzzer .

Los módulos rust_fuzz son una extensión de los módulos rust_binary y, como tales, comparten las mismas propiedades y consideraciones. Además, implementan muchas de las mismas propiedades y funcionalidades que los módulos cc_fuzz .

Al crear módulos rust_fuzz , se emite el indicador --cfg fuzzing que puede usarse para admitir la compilación condicional del código de la biblioteca para mejorar el fuzzing.

Escribe un fuzzer básico de Rust

Puede definir un módulo fuzz en un archivo de compilación Android.bp con este código:

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

El archivo fuzzer.rs contiene un fuzzer simple:

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

Aquí fuzz_target!(|data: &[u8]| { /* fuzz using data here */ }); define el punto de entrada fuzz-target llamado por el motor libFuzzer . El argumento data es una secuencia de bytes proporcionada por el motor libFuzzer que se manipulará como entrada para difuminar la función objetivo.

En este fuzzer de ejemplo, solo se verifica la longitud de los datos para determinar si se debe llamar a la función heap_oob , cuya llamada da como resultado una lectura fuera de límites. libFuzzer es un fuzzer guiado por cobertura, por lo que converge rápidamente en la longitud problemática ya que determina que los primeros 326 B de datos no dan como resultado nuevas rutas de ejecución.

Localice este ejemplo, en el árbol, en tools/security/fuzzing/example_rust_fuzzer/ . Para ver un ejemplo un poco más complejo de otro fuzzer (que difusa una dependencia rustlib ) en el árbol, consulte el archivo Legacy_blob_fuzzer .

Para obtener orientación sobre cómo escribir fuzzers de Rust con reconocimiento de estructuras , consulte el libro Rust Fuzz , la documentación oficial del proyecto Rust Fuzz.