A difusão de ferrugem é suportada por meio da caixa libfuzzer-sys
, que fornece ligações ao mecanismo de difusão libFuzzer do LLVM. Para obter mais informações, consulte o repositório libfuzzer-sys, bem como a página do projeto LLVM libFuzzer .
O módulo rust_fuzz
produz um binário fuzzer que começa a ser difuso quando é executado (semelhante aos módulos cc_fuzz
). Como o fuzzer aproveita o mecanismo de difusão libFuzzer
, podem ser necessários vários argumentos para controlar a difusão. Eles estão enumerados na documentação do libFuzzer .
Os módulos rust_fuzz
são uma extensão dos módulos rust_binary
e, como tal, compartilham as mesmas propriedades e considerações. Além disso, eles implementam muitas das mesmas propriedades e funcionalidades dos módulos cc_fuzz
.
Ao construir módulos rust_fuzz
, o sinalizador --cfg fuzzing
é emitido, o que pode ser usado para suportar a compilação condicional do código da biblioteca para melhorar a difusão.
Escreva um fuzzer Rust básico
Você pode definir um módulo fuzz em um arquivo de compilação Android.bp
com 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",
}
O arquivo fuzzer.rs
contém um fuzzer simples:
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();
}
});
Aqui fuzz_target!(|data: &[u8]| { /* fuzz using data here */ });
define o ponto de entrada do alvo fuzz chamado pelo mecanismo libFuzzer
. O argumento data
é uma sequência de bytes fornecida pelo mecanismo libFuzzer
para ser manipulada como entrada para confundir a função alvo.
Neste fuzzer de exemplo, apenas o comprimento dos dados é verificado para determinar se a função heap_oob
deve ser chamada, cuja chamada resulta em uma leitura fora dos limites. libFuzzer
é um fuzzer guiado por cobertura, portanto converge rapidamente para o comprimento problemático, pois determina que os primeiros 326 B de dados não resultam em novos caminhos de execução.
Localize este exemplo, na árvore, em tools/security/fuzzing/example_rust_fuzzer/ . Para ver um exemplo um pouco mais complexo de outro fuzzer (que difunde uma dependência rustlib
) na árvore, consulte legado_blob_fuzzer .
Para obter orientação sobre como escrever fuzzers Rust com reconhecimento de estrutura , consulte o livro Rust Fuzz , a documentação oficial do projeto Rust Fuzz.