Il fuzzing della ruggine è supportato attraverso la cassa di libfuzzer-sys
, che fornisce
associazioni al motore fuzzing libFuzzer di LLVM. Per ulteriori informazioni, consulta il repository libfuzzer-sys e la pagina del progetto LLVM libFuzzer.
Il modulo rust_fuzz
produce un file binario del fuzzer che inizia il fuzzing quando viene eseguito (simile ai moduli cc_fuzz
). Poiché il fuzzer sfrutta il motore di fuzzing libFuzzer
, può richiedere una serie di argomenti per controllarlo. Si tratta di
elencate nella documentazione di libFuzzer.
I moduli rust_fuzz
sono un'estensione di rust_binary
moduli e, come tali, condividono
le stesse proprietà e considerazioni. Inoltre, implementano molti dei
le stesse proprietà e funzionalità dei moduli cc_fuzz
.
Quando si creano moduli rust_fuzz
, viene emesso il flag --cfg fuzzing
, che può essere
da utilizzare per supportare la compilazione condizionale del codice libreria per migliorare il fuzzing.
Scrivere un semplice fuzzer di ruggine
Puoi definire un modulo fuzz in un file di build Android.bp
con questo codice:
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",
}
Il file fuzzer.rs
contiene un fuzzer semplice:
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();
}
});
Qui fuzz_target!(|data: &[u8]| { /* fuzz using data here */ });
definisce il punto di contatto del target di fuzz chiamato dal motore libFuzzer
. L'argomento data
è
una sequenza di byte fornita dal motore libFuzzer
da manipolare come input
per eseguire il fuzz della funzione scelta come target.
In questo esempio fuzzer, viene controllata solo la lunghezza dei dati per determinare
se chiamare la funzione heap_oob
, la cui chiamata genera
lettura oltre i limiti. libFuzzer
è un fuzzer guidato dalla copertura, quindi converge rapidamente
problematica, in quanto determina che i primi 326 B di dati non
daranno origine a nuovi percorsi di esecuzione.
Individua questo esempio all'interno dell'albero in tools/security/fuzzing/example_rust_fuzzer/.
Per visualizzare un esempio leggermente più complesso di un altro fuzzer (che genera un fuzzer rustlib
)
della dipendenza) nella struttura ad albero, vedi legacy_blob_fuzzer.
Per indicazioni su come scrivere fuzzer Rust attenti alla struttura, consulta il libro Rust Fuzz, la documentazione ufficiale del progetto Rust Fuzz.