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