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);
});

使用 Java API:

import com.code_intelligence.jazzer.api.FuzzedDataProvider;

import randomparcel.FuzzBinder;

public class ServiceFuzzer {

    static {
        // Initialize fuzzService and JNI dependencies
        FuzzBinder.init();
    }

    public static void fuzzerTestOneInput(FuzzedDataProvider data) {
        TestService service = new TestService();
        FuzzBinder.fuzzService(service, data.consumeRemainingAsBytes());
    }
}

如需了解构建设置,请参阅 Java Binder 服务模糊测试工具

AIDL 服务模糊测试框架

如上例所示,系统会在模糊测试工具中调用 fuzzService,后者会接受 IBinder (Service) 和 dataProvider 作为输入参数。它会先使用数据提供程序来初始化一个随机 Parcel 对象,然后通过使用输入 Parcel 对远程服务调用事务方法,最后将回复传入回复 Parcel。

构建系统会检查是否每项 AOSP Binder 服务在服务模糊测试工具绑定中都有对应的模糊测试工具条目。模糊测试工具绑定测试会检查 service_contexts 中的每个服务是否都有模糊测试工具。如果找不到新服务对应的模糊测试工具/异常,则表示存在构建错误。

可以通过添加以下代码来编写自动 C++ 服务模糊测试工具(尚不支持 Java 和 Rust 模糊测试工具):

  • Android.bp 中的 cc_fuzz 条目,用于定义模糊测试工具模块。cc_default 模块 service_fuzzer_defaults 具有 fuzzService 所需的依赖项。
  • 应以库或源代码的形式添加特定于服务的依赖项。
  • 用于构造服务并调用 fuzzService 的主文件

如需详细了解如何使用 cc_fuzz,请参阅通过 libFuzzer 进行模糊测试文档。如需解决构建错误,请使用新的服务和模糊测试工具名称更新绑定。对于 Java/Rust 服务,模糊测试工具列表可以为空。