وحدات المعلومات الثابتة

تتوفّر ميزة 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 بايت من البيانات لا يؤديان إلى مسارات تنفيذ جديدة.

ابحث عن هذا المثال in-tree على الرابط tools/security/fuzzing/example_rust_fuzzer/. لعرض مثال أكثر تعقيدًا إلى شجرة زغب أخرى (تتجاهل تبعية rustlib)، يمكنك الاطّلاع على Legacy_blob_fuzzer.

للحصول على إرشادات حول كيفية كتابة برامج Rust Fuzz التي تتضمّن ميزة فحص الأخطاء في البنية، اطّلِع على كتاب Rust Fuzz، وهو المستند الرسمي لمشروع Rust Fuzz.