फ़ज़ मॉड्यूल

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 बाइट से, नए एक्ज़ीक्यूशन पाथ नहीं मिलते हैं.

इस उदाहरण को इन-ट्री में tools/security/fuzzing/example_rust_fuzzer/ पर ढूंढें. इन-ट्री में मौजूद किसी अन्य फ़ज़र (जो rustlib डिपेंडेंसी को फ़ज़ करता है) का थोड़ा ज़्यादा मुश्किल उदाहरण देखने के लिए, legacy_blob_fuzzer देखें.

स्ट्रक्चर के बारे में जानकारी रखने वाले Rust फ़ज़र लिखने के तरीके के बारे में दिशा-निर्देश पाने के लिए, Rust Fuzz book देखें. यह Rust Fuzz प्रोजेक्ट का आधिकारिक दस्तावेज़ है.