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 服務的架構

如上例所示,fuzzService 會在模糊測試器中呼叫,並將 IBinder (服務) 和 dataProvider 做為輸入參數。首先,會使用資料提供者初始化隨機 Parcel 物件,然後使用輸入 Parcel 對遠端服務呼叫交易方法,最後將回覆傳送到回覆包裹。

建構及執行模糊測試工具

根據預設,系統會使用涵蓋率建構模糊測試器。

建議使用下列清理器來找出記憶體問題。hwaddress 消毒器只會在 arm 架構上執行:

SANITIZE_HOST=address SANITIZE_TARGET=hwaddress

使用 libFuzzer 執行時,Android.bp 檔案可能會指定字元集 (即目錄),您可以將這個目錄傳遞給模糊測試器。部分模糊工具也會在其 Android.bp 檔案中指定 dictionary:,而您可以使用 -dict path/to/dict 將此方法傳遞至 libFuzzer。如需更多選項,請參閱 官方 libFuzzer 說明文件

如要在裝置上執行模糊測試器,請依序執行 adb sync dataadb shell data/fuzz/arch/name/name。如要在主機上執行模糊測試器,請執行 $ANDROID_HOST_OUT/fuzz/arch/name/name

建構系統會檢查每個 AOSP 繫結器服務是否在服務模糊測試繫結中具有模糊測試項目。Fuzzer 繫結測試會檢查 service_contexts 中的每項服務是否都有 Fuzzer。如果找不到新服務的模糊測試或例外狀況,就表示有建構錯誤。

如要編寫自動 C++ 服務模糊測試工具,請新增下列項目 (目前尚不支援 Java 和 Rust 模糊測試工具):

  • Android.bp 中的 cc_fuzz 項目,用於定義模糊測試模組。cc_default 模組 service_fuzzer_defaults 具有 fuzzService 所需的依附元件。
  • 服務專屬的依附元件應新增為程式庫或來源。
  • 用來建構服務並呼叫 fuzzService 的主要檔案

如需 cc_fuzz 的詳細操作說明,請參閱「使用 libFuzzer 進行模糊測試」說明文件。如要解決建構錯誤,請使用新的服務和模糊測試器名稱更新繫結。如果是 Java 或 Rust 服務,模糊清單可以留空。