โมดูล Fuzz

รองรับการฟัซซิงแบบสนิมผ่านลัง libfuzzer-sys ซึ่งจัดเตรียมการเชื่อมโยงกับเอ็นจิ้นการฟัซซี่ libFuzzer ของ LLVM สำหรับข้อมูลเพิ่มเติม โปรดดูที่เก็บ libfuzzer-sys รวมถึง หน้าโปรเจ็กต์ LLVM libFuzzer

โมดูล rust_fuzz สร้างไบนารี fuzzer ซึ่งเริ่มคลุมเครือเมื่อทำงาน (คล้ายกับโมดูล cc_fuzz ) เนื่องจาก fuzzer ใช้ประโยชน์จากเอ็นจิ้น fuzzing libFuzzer จึงอาจต้องใช้ข้อโต้แย้งหลายประการในการควบคุม fuzzing สิ่งเหล่านี้ระบุไว้ใน เอกสารประกอบ libFuzzer

โมดูล rust_fuzz เป็นส่วนเสริมของโมดูล rust_binary และด้วยเหตุนี้จึงมีคุณสมบัติและข้อควรพิจารณาที่เหมือนกัน นอกจากนี้ ยังใช้คุณสมบัติและฟังก์ชันการทำงานหลายอย่างเช่นเดียวกับโมดูล cc_fuzz

เมื่อสร้างโมดูล rust_fuzz แฟล็ก --cfg fuzzing จะถูกปล่อยออกมา ซึ่งสามารถใช้เพื่อสนับสนุนการคอมไพล์โค้ดไลบรารีแบบมีเงื่อนไขเพื่อปรับปรุงการ fuzzing

เขียนตัวกันสนิมพื้นฐาน

คุณสามารถกำหนดโมดูล 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 อื่น (ซึ่ง fuzzes การพึ่งพา rustlib ) ในแผนผัง ให้ดูที่ Legacy_blob_fuzzer

สำหรับคำแนะนำเกี่ยวกับ วิธีการเขียน Rust fuzzers ที่คำนึงถึงโครงสร้าง โปรด ดู หนังสือ Rust Fuzz ซึ่งเป็นเอกสารอย่างเป็นทางการสำหรับโครงการ Rust Fuzz