تتوفّر ميزة اختبار التشويش في 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
يمكنك تحديد وحدة اختبار غير واضح في ملف إنشاء 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 */ });
نقطة الدخول إلى الاستهداف التقريبي التي يستدعيها المحرّك libFuzzer
. الوسيطة data
هي تسلسل من وحدات البايت يوفّره المحرّك libFuzzer
ليتم التعامل معه كإدخال لتشويش الدالة المستهدَفة.
في أداة التشويش هذه، يتم التحقّق من طول البيانات فقط لتحديد ما إذا كان سيتم استدعاء الدالة heap_oob
، ويؤدي استدعاؤها إلى قراءة خارج الحدود. libFuzzer
هي أداة فحص مبهم موجّهة بالتغطية، لذا فهي تتلاقى بسرعة مع الطول الذي يسبب المشكلة لأنّها تحدّد أنّ أول 326 بايت من البيانات لا تؤدي إلى مسارات تنفيذ جديدة.
يمكنك العثور على هذا المثال في الشجرة على المسار tools/security/fuzzing/example_rust_fuzzer/.
للاطّلاع على مثال أكثر تعقيدًا قليلاً لمموّه آخر (يُجري تمويهًا لملف rustlib
تابع) في الشجرة، يمكنك الاطّلاع على legacy_blob_fuzzer.
للحصول على إرشادات حول كيفية كتابة أدوات فحص غير واضح لبرامج Rust تراعي البنية، راجِع كتاب Rust Fuzz، وهو المستند الرسمي لمشروع Rust Fuzz.