فازینگ Rust از طریق جعبه libfuzzer-sys پشتیبانی میشود که اتصالاتی را برای موتور فازینگ libFuzzer LLVM فراهم میکند. برای اطلاعات بیشتر، به مخزن libfuzzer-sys و همچنین صفحه پروژه LLVM libFuzzer مراجعه کنید.
ماژول rust_fuzz یک فایل باینری fuzzer تولید میکند که هنگام اجرا شروع به fuzzing میکند (مشابه ماژولهای cc_fuzz ). از آنجایی که fuzzer از موتور fuzzer libFuzzer استفاده میکند، میتواند تعدادی آرگومان برای کنترل fuzzing دریافت کند. این آرگومانها در مستندات 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 شامل یک fuzzer ساده است:
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 یک فازر هدایتشده توسط پوشش است، بنابراین به سرعت روی طول مشکلساز همگرا میشود زیرا تعیین میکند که ۳۲۶ بایت اول دادهها منجر به مسیرهای اجرایی جدید نمیشوند.
این مثال را در شاخهی درختی، در tools/security/fuzzing/example_rust_fuzzer/ پیدا کنید. برای مشاهدهی یک مثال کمی پیچیدهتر از یک fuzzer دیگر (که یک وابستگی rustlib fuzz میکند) در شاخهی درختی، به legacy_blob_fuzzer مراجعه کنید.
برای راهنمایی در مورد نحوه نوشتن فازرهای Rust آگاه از ساختار ، به کتاب Rust Fuzz ، مستندات رسمی پروژه Rust Fuzz، مراجعه کنید.