Фаззинг Rust поддерживается через крейт libfuzzer-sys
, который обеспечивает привязки к движку фаззинга libFuzzer LLVM. Дополнительную информацию см. в репозитории libfuzzer-sys , а также на странице проекта LLVM libFuzzer .
rust_fuzz
создает двоичный файл фаззера, который начинает фаззинг при запуске (аналогично модулям cc_fuzz
). Поскольку фаззер использует механизм фаззинга libFuzzer
, он может принимать ряд аргументов для управления фаззингом. Они перечислены в документации libFuzzer .
Модули rust_fuzz
являются расширением модулей rust_binary
и поэтому имеют те же свойства и особенности. Кроме того, они реализуют многие из тех же свойств и функций, что и модули cc_fuzz
.
При сборке модулей rust_fuzz
выдается флаг --cfg fuzzing
, который можно использовать для поддержки условной компиляции библиотечного кода для улучшения фаззинга.
Напишите базовый фаззер Rust
Вы можете определить модуль fuzz в файле сборки Android.bp
с помощью этого кода:
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",
}
Файл fuzzer.rs
содержит простой фаззер:
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();
}
});
Здесь fuzz_target!(|data: &[u8]| { /* fuzz using data here */ });
определяет точку входа fuzz-target, вызываемую движком libFuzzer
. Аргумент data
— это последовательность байтов, предоставляемая механизмом libFuzzer
которая используется в качестве входных данных для фаззинга целевой функции.
В этом примере фаззера проверяется только длина данных, чтобы определить, следует ли вызывать функцию heap_oob
, вызов которой приводит к чтению за пределами допустимого диапазона. libFuzzer
— это фаззер, управляемый покрытием, поэтому он быстро сходится к проблемной длине, поскольку определяет, что первые 326 байт данных не приводят к новым путям выполнения.
Найдите этот пример в дереве по адресуtools/security/fuzzing/example_rust_fuzzer/ . Чтобы просмотреть немного более сложный пример другого фаззера (который фаззит зависимость rustlib
) в дереве, см. Legacy_blob_fuzzer .
Рекомендации по написанию фаззеров Rust с учетом структуры см. в книге Rust Fuzz , официальной документации проекта Rust Fuzz.