תמיכה ב-Rust fuzzing ניתנת באמצעות ה-crate libfuzzer-sys
, שמספק קישורים למנוע ה-fuzzing libFuzzer של LLVM. למידע נוסף, ראו libfuzzer-sys ודף הפרויקט LLVM libFuzzer.
המודול rust_fuzz
יוצר קובץ בינארי של fuzzer שמתחיל לבצע fuzzing כשמריצים אותו (בדומה למודול cc_fuzz
). מכיוון שה-fuzzer ממנף את מנוע ההתעבות libFuzzer
, יכולים להיות מספר ארגומנטים כדי לשלוט ב-fuzzing. הם מפורטים במסמכי התיעוד של libFuzzer.
מודולים של rust_fuzz
הם הרחבה של מודולים של rust_binary
, ולכן הם חולקים את אותם מאפיינים ושיקולים. בנוסף, הם מטמיעים הרבה מהמאפיינים והפונקציונליות של המודולים cc_fuzz
.
כשמפתחים מודולים של rust_fuzz
, מושמע הדגל --cfg fuzzing
כדי לתמוך בהידור מותנה של קוד הספרייה כדי לשפר את fuzzing.
כתיבה של מפוצץ חלודה בסיסי
אפשר להגדיר מודול fuzz בקובץ build של 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
מכיל כלי fuzzing פשוט:
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
כך שניתן לשנות אותם כקלט כדי לבצע fuzz מנתונים של הפונקציה המטורגטת.
בדוגמה הזו של ה-fuzzer, רק אורך הנתונים נבדק כדי לקבוע אם להפעיל את הפונקציה heap_oob
, שהפעלה שלה גורמת לקריאה מחוץ למגבלות. libFuzzer
הוא fuzzing מוכוון כיסוי, לכן הוא מתכנס במהירות לאורך הבעייתי כי הוא קובע ש-326B הראשונים של הנתונים לא מובילים לנתיבי הפעלה חדשים.
את הדוגמה הזו אפשר למצוא בתוך העץ בכתובת tools/security/fuzzing/example_rust_fuzzer/.
כדי לראות דוגמה קצת יותר מורכבת ל-fuzzer אחר (שהופך את התלות ב-rustlib
) לעץ, עיינו ב-Legacy_blob_fuzzer.
לקבלת הנחיות לכתיבה של כלי fuzzing מבוססי-מבנה ב-Rust, תוכלו לעיין בספר Rust Fuzz, המסמך הרשמי של פרויקט Rust Fuzz.