تخطَّ إلى المحتوى

cargo-fuzz - Fuzzing Rust مع libFuzzer

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_inputFuzz الـ target
cargo fuzz run parse_input -- -max_total_time=300تشغيل 5 دقائق
cargo fuzz run parse_input -j 88 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 targetsFuzz APIs و ليس فقط parsers
Debug outputقابل للقراءة reproducers

Sanitizers

Sanitizerالعلم
AddressSanitizer (افتراضي)-s address
LeakSanitizerincluded 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 / deserializersUntrusted input و complex state
unsafe blocksذاكرة الأمان بالفعل في الخطر
FFI boundariesC code خلف الواجهة
Protocol/state machinesOrdering bugs
Compression / encodingClassic bug territory
أقل مفيدلماذا
Pure safe arithmeticPanics غالباً ما تكون واضحة
Thin wrappersمنطق قليل للاستكشاف

cargo-fuzz مقابل Fuzzers الأخرى

الجانبcargo-fuzzAFL++ (afl.rs)LibAFLhonggfuzz-rs
محركlibFuzzerAFL++Customhonggfuzz
الإعدادالأسهل ل Rustمعتدلبناء الخاص بكسهل
منظم inputarbitraryarbitraryCustom typesarbitrary
الأفضل للـStandard Rust fuzzingPersistent/binary modesأهداف غير عاديةHardware feedback

لأهداف non-Rust انظر AFL++ أو honggfuzz; لـ custom fuzzers انظر LibAFL.

الموارد