การฟัซ Rust ได้รับการรองรับผ่าน Crate libfuzzer-sys ซึ่งมี
การเชื่อมโยงกับเครื่องมือฟัซ libFuzzer ของ LLVM ดูข้อมูลเพิ่มเติมได้ที่ที่เก็บ libfuzzer-sys
รวมถึงหน้าโปรเจ็กต์ LLVM libFuzzer
rust_fuzz โมดูลจะสร้างไบนารีของ Fuzzer ซึ่งจะเริ่ม Fuzzing เมื่อมีการเรียกใช้ (คล้ายกับโมดูล cc_fuzz) เนื่องจาก Fuzzer ใช้ประโยชน์จากlibFuzzer
Fuzzing Engine จึงสามารถรับอาร์กิวเมนต์จำนวนมากเพื่อควบคุมการฟัซได้ ซึ่งระบุไว้ในเอกสารประกอบ libFuzzer
rust_fuzz เป็นส่วนขยายของโมดูล rust_binary จึงมีพร็อพเพอร์ตี้และข้อควรพิจารณาเหมือนกัน
นอกจากนี้ ยังใช้พร็อพเพอร์ตี้และฟังก์ชันการทำงานหลายอย่างเหมือนกับโมดูล cc_fuzz
เมื่อสร้างrust_fuzzโมดูล ระบบจะปล่อยแฟล็ก --cfg fuzzing ซึ่งใช้เพื่อรองรับการคอมไพล์แบบมีเงื่อนไขของโค้ดไลบรารีเพื่อปรับปรุงการฟัซได้
เขียน Fuzzer พื้นฐานใน Rust
คุณกำหนดโมดูล 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 */ }); จะกำหนด
จุดแรกเข้าของเป้าหมายการฟัซ ซึ่งเรียกใช้โดยเครื่องมือ libFuzzer อาร์กิวเมนต์ data คือ
ลำดับไบต์ที่เครื่องมือ libFuzzer จัดเตรียมไว้เพื่อใช้เป็นอินพุต
ในการฟัซฟังก์ชันเป้าหมาย
ใน Fuzzer ตัวอย่างนี้ ระบบจะตรวจสอบเฉพาะความยาวของข้อมูลเพื่อพิจารณาว่าจะเรียกใช้ฟังก์ชัน heap_oob หรือไม่ ซึ่งการเรียกใช้จะส่งผลให้เกิดการอ่านที่อยู่นอกขอบเขต libFuzzer เป็น Fuzzer ที่มีคำแนะนำด้านความครอบคลุม จึงเข้าถึงความยาวที่เป็นปัญหาได้อย่างรวดเร็ว เนื่องจากพิจารณาว่าข้อมูล 326 ไบต์แรกไม่ทำให้เกิดเส้นทางการดำเนินการใหม่
ค้นหาตัวอย่างนี้ในโครงสร้างที่ tools/security/fuzzing/example_rust_fuzzer/
หากต้องการดูตัวอย่างที่ซับซ้อนขึ้นเล็กน้อยของ Fuzzer อื่น (ซึ่ง Fuzz rustlib
Dependency) ในทรี โปรดดู legacy_blob_fuzzer
ดูคำแนะนำเกี่ยวกับวิธีเขียน Fuzzer ใน Rust ที่รับรู้โครงสร้างได้ที่หนังสือ Rust Fuzz ซึ่งเป็นเอกสารอย่างเป็นทางการสำหรับโปรเจ็กต์ Rust Fuzz