AIDL 模糊測試

模糊器透過產生的存根導入/呼叫遠端服務,充當遠端服務的客戶端:

使用 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 服務的框架

如上例所示,fuzzer 中呼叫了fuzzService ,並接受 IBinder(Service)和 dataProvider 作為輸入參數。它首先使用資料提供者初始化一個隨機 Parcel 對象,並使用輸入的 Parcel 呼叫遠端服務上的 transact 方法,最後將回應取得到回應 Parcel 中。

建置並運行模糊器

預設情況下,模糊器是透過覆蓋率建構的。

建議使用以下清理程序來發現記憶體問題。 hwaddress sanitizers 僅在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

建置系統檢查每個 AOSP 綁定器服務在服務模糊器綁定中是否有模糊器條目。模糊器綁定測試檢查service_contexts中的每個服務是否都有模糊器。如果未找到新服務的模糊器/異常,則存在建置錯誤。

可以透過新增以下內容來編寫自動 C++ 服務模糊器(尚不支援 Java 和 Rust 模糊器):

  • Android.bp中的cc_fuzz條目用於定義模糊器模組。 cc_default模組service_fuzzer_defaults具有fuzzService所需的依賴項。
  • 特定於服務的依賴項應作為庫或來源添加。
  • 建置服務並呼叫fuzzService的主文件

有關使用cc_fuzz詳細說明,請參閱使用 libFuzzer 進行模糊測試文件。若要解決建置錯誤,請使用新的服務和模糊器名稱更新綁定。對於 Java/Rust 服務,模糊器清單可以為空。