وحدات Fuzz

تتوفّر ميزة Rust fuzzing من خلال حزمة 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 Fuzz التي تتضمّن ميزة فحص الأخطاء في البنية، اطّلِع على كتاب Rust Fuzz، وهو المستند الرسمي لمشروع Rust Fuzz.