फ़ज़ मॉड्यूल

libfuzzer-sys क्रेट की मदद से, Rust में फ़ज़िंग की जा सकती है. यह क्रेट, 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/ पर ढूंढें. ट्री में, किसी दूसरे फ़ज़र का थोड़ा ज़्यादा जटिल उदाहरण देखने के लिए, legacy_blob_fuzzer देखें. यह फ़ज़र, rustlib डिपेंडेंसी को फ़ज़ करता है.

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