AIDL 퍼징

Fuzzer는 생성된 스텁을 통해 원격 서비스를 가져오거나 호출하여 원격 서비스의 클라이언트처럼 작동합니다.

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를 호출하고 fuzzService는 IBinder(서비스)와 dataProvider를 입력 매개변수로 사용합니다. 먼저 데이터 제공업체를 사용하여 임의의 Parcel 객체를 초기화하고 입력 parcel을 사용하여 원격 서비스에서 transact 메서드를 호출합니다. 그런 다음 마지막으로 응답 parcel에 응답을 가져옵니다.

빌드 시스템은 모든 AOSP 바인더 서비스의 서비스 fuzzer 결합에 fuzzer 항목이 있는지 확인합니다. Fuzzer 바인딩 테스트는 service_contexts의 모든 서비스에 fuzzer가 있는지 확인합니다. 새 서비스에 fuzzer/예외가 없으면 빌드 오류가 발생합니다.

다음을 추가하여 자동 C++ 서비스 fuzzer를 작성할 수 있습니다(Java 및 Rust fuzzer는 아직 지원되지 않음).

  • Android.bpcc_fuzz 항목을 사용해 fuzzer 모듈을 정의합니다. cc_default 모듈 service_fuzzer_defaultsfuzzService에 요구되는 종속 항목을 갖습니다.
  • 서비스별 종속 항목은 라이브러리 또는 소스로 추가되어야 합니다.
  • 서비스를 구성하며 fuzzService를 호출하는 기본 파일입니다.

cc_fuzz 사용에 관한 자세한 안내는 libFuzzer를 사용한 퍼징 문서를 참고하세요. 빌드 오류를 해결하려면 새 서비스와 fuzzer 이름으로 결합을 업데이트하세요. Java/Rust 서비스의 경우 fuzzer 목록이 비어 있을 수 있습니다.