Rust fuzzing es compatible 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 , así como la página del proyecto LLVM libFuzzer .
El módulo rust_fuzz
produce un fuzzer binario que comienza a fuzzear cuando se ejecuta (similar a los módulos cc_fuzz
). Como el fuzzer aprovecha el motor de fuzzing de libFuzzer
, puede tomar una serie de argumentos para controlar el fuzzing. 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 funciones que los módulos cc_fuzz
.
Escribiendo un Rust fuzzer básico
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 del objetivo fuzz llamado por el motor libFuzzer
. El argumento data
es una secuencia de bytes proporcionados por el motor libFuzzer
para ser manipulados como entrada para fuzzear la función de destino.
En este fuzzer de ejemplo, solo se comprueba 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 los límites. libFuzzer
es un fuzzer guiado por cobertura, por lo que converge rápidamente en la longitud problemática al determinar que los primeros 326 B de datos no dan como resultado nuevas rutas de ejecución.
Busque 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 rustlib
una dependencia de rustlib) en el árbol, consulte legacy_blob_fuzzer .
Para obtener orientación sobre cómo escribir fuzzers de Rust conscientes de la estructura , consulte el libro Rust Fuzz , la documentación oficial del proyecto Rust Fuzz.