AIDL Fuzzing, AIDL Fuzzing

O fuzzer se comporta como um cliente para o serviço remoto importando/invocando-o através do stub gerado:

Usando API C++:

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

Usando API Rust:

#![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);
});

Estrutura para difundir serviços AIDL

Conforme mostrado no exemplo acima, fuzzService é chamado no fuzzer e recebe um IBinder (Service) e dataProvider como parâmetros de entrada. Ele primeiro inicializa um objeto Parcel aleatório usando o provedor de dados e chama o método transact no serviço remoto usando o pacote de entrada e, finalmente, obtém a resposta em um pacote de resposta.

Crie e execute fuzzers

Os Fuzzers são construídos com cobertura por padrão.

Os seguintes desinfetantes são recomendados para descobrir problemas de memória. Os sanitizadores hwaddress funcionam apenas na arquitetura arm :

SANITIZE_HOST=address SANITIZE_TARGET=hwaddress

Ao executar com libFuzzer , um corpus, que é um diretório, pode ser especificado no arquivo Android.bp e você pode passar esse diretório para o fuzzer. Alguns fuzzers também especificam um dictionary: em seu arquivo Android.bp , e você pode passar isso para libFuzzer com -dict path/to/dict . Para mais opções, consulte a documentação oficial do libFuzzer .

Para executar fuzzers no dispositivo, execute adb sync data e então adb shell data/fuzz/ arch / name / name . Para executar fuzzers no host, execute $ANDROID_HOST_OUT/ fuzz / arch / name / name .

O sistema de compilação verifica se cada serviço de binder AOSP possui uma entrada de fuzzer em service fuzzer bindings . O teste de ligação do Fuzzer verifica se cada serviço em service_contexts possui um fuzzer. Se um fuzzer/exceção não for encontrado para um novo serviço, há um erro de compilação.

Um fuzzer de serviço C++ automático pode ser escrito adicionando o seguinte (fuzzers Java e Rust ainda não são suportados):

  • Uma entrada cc_fuzz em Android.bp para definir o módulo fuzzer. O módulo cc_default service_fuzzer_defaults possui dependências necessárias para fuzzService .
  • As dependências específicas do serviço devem ser adicionadas como uma biblioteca ou como fontes.
  • Um arquivo principal que constrói seu serviço e chama fuzzService

Para obter instruções detalhadas sobre como usar cc_fuzz , consulte a documentação Fuzzing com libFuzzer . Para resolver o erro de construção, atualize as ligações com os novos nomes de serviço e fuzzer. Para serviços Java/Rust, a lista de fuzzers pode estar vazia.