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(Service)と dataProvider を入力パラメータとして受け取ります。まず、データ プロバイダを使用して、ランダムな Parcel オブジェクトを初期化し、入力 Parcel を使用してリモート サービスで transact メソッドを呼び出して、最後に応答 Parcel にレスポンスを取得します。

ファザーをビルドして実行する

ファザーは、デフォルトでカバレッジ付きでビルドされます。

以下のサニタイザーを使用してメモリの問題を特定することを推奨します。hwaddress サニタイザーは、arm アーキテクチャでのみ実行されます。

SANITIZE_HOST=address SANITIZE_TARGET=hwaddress

libFuzzer で実行する場合、コーパス(ディレクトリ)を Android.bp ファイルで指定して、このディレクトリをファザーに渡すことができます。一部のファザーは dictionary:Android.bp ファイルで指定します。これは、-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 サービスの場合、ファザーリストは空にできます。