cargo-fuzz - Fuzzing Rust مع libFuzzer
cargo-fuzz هي الطريقة القياسية لـ fuzz Rust code. إنها تربط libFuzzer مع سير عمل Cargo-native: اكتب fuzz target كدالة Rust عادية تأخذ bytes عشوائية و شغل cargo fuzz run و coverage-guided fuzzing يبحث عن panics و arithmetic overflows و — في unsafe code — أخطاء ذاكرة حقيقية. آمنة Rust تمنع تلف الذاكرة لكنها لا تمنع panics و حلقات لا نهائية أو أخطاء منطق و أي unsafe block أو C dependency تعيد إدخال الفئة الكاملة من مشاكل الذاكرة.
التثبيت
| الخطوة | الأمر |
|---|
| التثبيت | cargo install cargo-fuzz |
| Nightly مطلوبة | rustup install nightly (libFuzzer يحتاج nightly) |
| تهيئة | cargo fuzz init (في crate الخاص بك) |
| التحقق | cargo fuzz --version |
إنشاء Fuzz Target
cargo fuzz init # creates fuzz/ directory
cargo fuzz add parse_input # creates a new target
// fuzz/fuzz_targets/parse_input.rs
#![no_main]
use libfuzzer_sys::fuzz_target;
fuzz_target!(|data: &[u8]| {
if let Ok(s) = std::str::from_utf8(data) {
let _ = my_crate::parse(s); // panics here become findings
}
});
التشغيل
| الأمر | الوصف |
|---|
cargo fuzz run parse_input | Fuzz الـ target |
cargo fuzz run parse_input -- -max_total_time=300 | تشغيل 5 دقائق |
cargo fuzz run parse_input -j 8 | 8 parallel jobs |
cargo fuzz list | قائمة الـ targets |
cargo fuzz build | بناء بدون تشغيل |
منظم الإدخال مع Arbitrary
raw bytes إهدار وقت على inputs محلل الخاص بك يرفضها على الفور. arbitrary crate يبني قيم مكتوبة بدلاً من ذلك:
use arbitrary::Arbitrary;
#[derive(Arbitrary, Debug)]
struct Config { name: String, retries: u8, enabled: bool }
fuzz_target!(|cfg: Config| {
let _ = my_crate::apply_config(cfg);
});
| الفائدة | لماذا |
|---|
| Valid-shaped inputs | يصل منطق أعمق |
| Typed targets | Fuzz APIs و ليس فقط parsers |
Debug output | قابل للقراءة reproducers |
Sanitizers
| Sanitizer | العلم |
|---|
| AddressSanitizer (افتراضي) | -s address |
| LeakSanitizer | included with ASan |
| MemorySanitizer | -s memory |
| ThreadSanitizer | -s thread |
| None (أسرع) | -s none |
# Fuzz unsafe FFI code مع ASan
cargo fuzz run ffi_target -s address
Corpus و التغطية
| الأمر | الغرض |
|---|
fuzz/corpus/<target>/ | حيث مثيرة للاهتمام inputs جمع |
cargo fuzz cmin <target> | قلل corpus |
cargo fuzz tmin <target> <input> | قلل crashing input |
cargo fuzz coverage <target> | توليد coverage data |
| Seed corpus | أضف أمثلة صالحة للـ bootstrap |
Seeding corpus مع real صالح inputs هي طريقة الأكثر فعالية لجعل fuzzing منتج بسرعة.
إعادة إنتاج الأعطال
# Crashes تهبط في fuzz/artifacts/<target>/
cargo fuzz run parse_input fuzz/artifacts/parse_input/crash-abc123
# Shrink إلى حالة الحد الأدنى
cargo fuzz tmin parse_input fuzz/artifacts/parse_input/crash-abc123
تحويل minimized input إلى regular #[test] حتى يبقى bug مثبت.
ماذا تفعل Fuzz في Rust
| الهدف الجيد | لماذا |
|---|
| Parsers / deserializers | Untrusted input و complex state |
unsafe blocks | ذاكرة الأمان بالفعل في الخطر |
| FFI boundaries | C code خلف الواجهة |
| Protocol/state machines | Ordering bugs |
| Compression / encoding | Classic bug territory |
| أقل مفيد | لماذا |
|---|
| Pure safe arithmetic | Panics غالباً ما تكون واضحة |
| Thin wrappers | منطق قليل للاستكشاف |
cargo-fuzz مقابل Fuzzers الأخرى
| الجانب | cargo-fuzz | AFL++ (afl.rs) | LibAFL | honggfuzz-rs |
|---|
| محرك | libFuzzer | AFL++ | Custom | honggfuzz |
| الإعداد | الأسهل ل Rust | معتدل | بناء الخاص بك | سهل |
| منظم input | arbitrary | arbitrary | Custom types | arbitrary |
| الأفضل للـ | Standard Rust fuzzing | Persistent/binary modes | أهداف غير عادية | Hardware feedback |
لأهداف non-Rust انظر AFL++ أو honggfuzz; لـ custom fuzzers انظر LibAFL.
الموارد