एआईडीएल फ़ज़िंग

फ़ज़र, रिमोट सेवा के लिए क्लाइंट के तौर पर काम करता है. इसके लिए, वह जनरेट किए गए स्टब के ज़रिए सेवा को इंपोर्ट या शुरू करता है:

C++ API का इस्तेमाल करके:

#include <fuzzbinder/libbinder_ndk_driver.h>
#include <fuzzer/FuzzedDataProvider.h>

#include <android-base/logging.h>
#include <android/binder_interface_utils.h>

using android::fuzzService;
using ndk::SharedRefBase;

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
    auto binder = ndk::SharedRefBase::make<MyService>(...);

    fuzzService(binder->asBinder().get(), FuzzedDataProvider(data, size));

    return 0;
}

Rust API का इस्तेमाल करके:

#![allow(missing_docs)]
#![no_main]
#[macro_use]
extern crate libfuzzer_sys;

use binder::{self, BinderFeatures, Interface};
use binder_random_parcel_rs::fuzz_service;

fuzz_target!(|data: &[u8]| {
    let service = BnTestService::new_binder(MyService, BinderFeatures::default());
    fuzz_service(&mut service.as_binder(), data);
});

AIDL सेवाओं को फ़ज़ करने के लिए फ़्रेमवर्क

ऊपर दिए गए उदाहरण में दिखाया गया है कि fuzzService को फ़ज़र में कॉल किया जाता है. साथ ही, यह IBinder (Service) और dataProvider को इनपुट पैरामीटर के तौर पर लेता है. यह सबसे पहले, डेटा प्रोवाइडर का इस्तेमाल करके, किसी रैंडम पार्सल ऑब्जेक्ट को शुरू करता है. इसके बाद, इनपुट पार्सल का इस्तेमाल करके, रिमोट सेवा पर ट्रांसैक्ट तरीके को कॉल करता है. आखिर में, जवाब को जवाब वाले पार्सल में पाता है.

फ़ज़र बनाना और उन्हें चलाना

फ़ज़र्स को डिफ़ॉल्ट रूप से कवरेज के साथ बनाया जाता है.

मेमोरी से जुड़ी समस्याओं का पता लगाने के लिए, इन सैनिटाइज़र का इस्तेमाल करने का सुझाव दिया जाता है. hwaddress सैनिटाइज़र सिर्फ़ arm आर्किटेक्चर पर काम करते हैं:

SANITIZE_HOST=address SANITIZE_TARGET=hwaddress

libFuzzer के साथ फ़ज़िंग करते समय, Android.bp फ़ाइल में एक कॉर्पस (डायरेक्ट्री) तय किया जा सकता है. साथ ही, इस डायरेक्ट्री को फ़ज़र को पास किया जा सकता है. कुछ फ़ज़र, अपनी Android.bp फ़ाइल में dictionary: भी तय करते हैं. साथ ही, -dict path/to/dict की मदद से इसे libFuzzer को पास किया जा सकता है. ज़्यादा विकल्पों के लिए, libFuzzer का आधिकारिक दस्तावेज़ देखें.

डिवाइस पर फ़ज़र चलाने के लिए, adb sync data और फिर adb shell data/fuzz/arch/name/name चलाएं. होस्ट पर फ़ज़र चलाने के लिए, $ANDROID_HOST_OUT/fuzz/arch/name/name चलाएं.

बिल्ड सिस्टम यह जांच करता है कि हर एओएसपी बाइंडर सेवा के लिए, सेवा फ़ज़र बाइंडिंग में फ़ज़र एंट्री मौजूद है या नहीं. Fuzzer बाइंडिंग टेस्ट से यह पता चलता है कि service_contexts में मौजूद हर सेवा के लिए, फ़ज़र मौजूद है या नहीं. अगर किसी नई सेवा के लिए फ़ज़र या अपवाद नहीं मिलता है, तो बिल्ड में गड़बड़ी होती है.

C++ सेवा के लिए, अपने-आप काम करने वाला फ़ज़र बनाया जा सकता है. इसके लिए, यह कोड जोड़ें (Java और Rust फ़ज़र फ़िलहाल काम नहीं करते):

  • फ़ज़र मॉड्यूल को तय करने के लिए, Android.bp में cc_fuzz एंट्री. cc_default मॉड्यूल service_fuzzer_defaults में, fuzzService के लिए ज़रूरी डिपेंडेंसी हैं.
  • सेवा से जुड़ी डिपेंडेंसी को लाइब्रेरी या सोर्स के तौर पर जोड़ा जाना चाहिए.
  • मुख्य फ़ाइल, जो आपकी सेवा को बनाती है और fuzzService को कॉल करती है

cc_fuzz का इस्तेमाल करने के बारे में ज़्यादा जानकारी के लिए, libFuzzer की मदद से फ़ज़िंग करना दस्तावेज़ देखें. बिल्ड से जुड़ी गड़बड़ी को ठीक करने के लिए, नई सेवा और फ़ज़र के नामों के साथ बाइंडिंग अपडेट करें. Java या Rust सेवाओं के लिए, फ़ज़र की सूची खाली हो सकती है.