Rust फ़ज़िंग की सुविधा, libfuzzer-sys
क्रेट की मदद से काम करती है. यह LLVM के libFuzzer फ़ज़िंग इंजन को बाइंडिंग उपलब्ध कराती है. ज़्यादा जानकारी के लिए, 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 B से, नए एक्सीक्यूशन पाथ नहीं मिलते.
इस उदाहरण को ट्री में, tools/security/fuzzing/example_rust_fuzzer/ पर ढूंढें.
इन-ट्री में मौजूद किसी फ़ज़र (जो rustlib
डिपेंडेंसी को फ़ज़ करता है) का थोड़ा ज़्यादा मुश्किल उदाहरण देखने के लिए, legacy_blob_fuzzer देखें.
स्ट्रक्चर के बारे में जानकारी देने वाले Rust फ़ज़र लिखने का तरीका जानने के लिए, Rust फ़ज़र की किताब देखें. यह Rust फ़ज़र प्रोजेक्ट का आधिकारिक दस्तावेज़ है.