ماژول های فاز

Rust fuzzing از طریق جعبه libfuzzer-sys پشتیبانی می شود، که اتصالات را به موتور فازی libFuzzer LLVM ارائه می کند. برای اطلاعات بیشتر، به مخزن libfuzzer-sys و همچنین صفحه پروژه LLVM libFuzzer مراجعه کنید.

ماژول rust_fuzz یک باینری fuzzer تولید می کند که هنگام اجرا شروع به فاز شدن می کند (شبیه به ماژول های cc_fuzz ). همانطور که فازر از موتور فازی libFuzzer استفاده می کند، می تواند چندین آرگومان برای کنترل فازی شدن نیاز داشته باشد. اینها در مستندات libFuzzer برشمرده شده اند.

ماژول‌های rust_fuzz توسعه‌ای از ماژول‌های rust_binary هستند و به این ترتیب ویژگی‌ها و ملاحظات یکسانی دارند. علاوه بر این، آنها بسیاری از ویژگی ها و عملکردهای مشابه ماژول های cc_fuzz را پیاده سازی می کنند.

هنگام ساخت ماژول‌های rust_fuzz ، پرچم --cfg fuzzing منتشر می‌شود که می‌تواند برای پشتیبانی از کامپایل شرطی کد کتابخانه برای بهبود فازبندی استفاده شود.

یک Rust fuzzer اولیه بنویسید

شما می توانید یک ماژول fuzz را در یک فایل ساخت 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 حاوی یک fuzzer ساده است:

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 */ }); نقطه ورودی fuzz-target را تعریف می کند که توسط موتور libFuzzer فراخوانی شده است. آرگومان data ، دنباله ای از بایت ها است که توسط موتور libFuzzer ارائه می شود تا به عنوان ورودی برای فازی کردن تابع هدف دستکاری شود.

در این fuzzer مثال، فقط طول داده بررسی می شود تا مشخص شود که آیا تابع heap_oob فراخوانی شود، فراخوانی آن منجر به خواندن خارج از محدوده می شود. libFuzzer یک fuzzer هدایت پوشش است، بنابراین به سرعت در طول مشکل همگرا می شود زیرا تعیین می کند که 326 B اول داده منجر به مسیرهای اجرایی جدید نمی شود.

این مثال را در داخل درخت در tools/security/fuzzing/example_rust_fuzzer/ پیدا کنید. برای مشاهده یک مثال کمی پیچیده‌تر از fuzzer دیگر (که وابستگی rustlib را از بین می‌برد) در درخت، به legacy_blob_fuzzer مراجعه کنید.

برای راهنمایی در مورد نحوه نوشتن Rust fuzzers آگاه از ساختار ، به کتاب Rust Fuzz ، مستندات رسمی پروژه Rust Fuzz مراجعه کنید.