फ़ज़ मॉड्यूल

रस्ट फ़ज़िंग, libfuzzer-sys क्रेट के ज़रिए काम करती है. यह एलएलवीएम के लिबफ़ज़ज़र फ़ज़िंग इंजन को बाइंडिंग उपलब्ध कराता है. ज़्यादा जानकारी के लिए, libfuzzer-sys का डेटा स्टोर करने की जगह देखें. साथ ही, LLVM libFazzer प्रोजेक्ट पेज भी देखें.

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, कवरेज के निर्देशों वाला फ़ज़्ज़र है. इसलिए, यह समस्या वाले पेज की लंबाई को तुरंत एक साथ दिखाता है, क्योंकि इससे पता चलता है कि पहले 326B डेटा के लिए, एक्ज़ीक्यूशन पाथ का इस्तेमाल नहीं किया जाता.

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

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