O fuzzer se comporta como um cliente do serviço remoto, importando ou invocando o stub gerado:
Como usar a 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;
}
Como usar a 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);
});
Framework para fazer fuzz de serviços AIDL
Como mostrado no exemplo acima, fuzzService é chamado no fuzzer e recebe um IBinder (serviço) e um dataProvider como parâmetros de entrada. Primeiro, ele inicializa um objeto Parcel aleatório usando o provedor de dados e chama o método de transação no serviço remoto usando o pacote de entrada. Por fim, ele recebe a resposta em um pacote de resposta.
Criar e executar fuzzers
Os fuzzers são criados com cobertura por padrão.
Os sanitizadores a seguir são recomendados para descobrir problemas de memória.
Os limpadores hwaddress
são executados 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 transmitir esse diretório para o fuzzer. Alguns
fuzzers também especificam um dictionary:
no arquivo Android.bp
, e você pode
transmitir isso para o libFuzzer com -dict path/to/dict
. Para
mais opções, consulte a
documentação oficial do libFuzzer (link em inglês).
Para executar fuzzers no dispositivo, execute adb sync data
e
adb shell data/fuzz/arch/name/name
.
Para executar fuzzers no host, execute
$ANDROID_HOST_OUT/fuzz/arch/name/name
.
Recomendar fuzzers para serviços novos ou existentes
O sistema de build verifica se cada serviço de vinculação do AOSP tem uma entrada de fuzzer nas
vinculações de fuzzer de serviço.
O teste de vinculação do fuzzer verifica se todos os serviços em service_contexts
têm um
fuzzer. Se um fuzzer ou uma exceção não for encontrado para um novo serviço, haverá um erro de build.
Um fuzzer de serviço C++ automático pode ser escrito adicionando o seguinte (os fuzzers Java e Rust ainda não têm suporte):
- Uma entrada
cc_fuzz
emAndroid.bp
para definir o módulo de fuzzer. O móduloservice_fuzzer_defaults
docc_default
tem dependências necessárias parafuzzService
. - As dependências específicas do serviço precisam ser adicionadas como uma biblioteca ou como fontes.
- Um arquivo principal que constrói seu serviço e chama
fuzzService
Para instruções detalhadas sobre como usar cc_fuzz
, consulte a
documentação
Fuzzing com libFuzzer. Para resolver o erro de build, atualize as vinculações com o novo serviço e
os nomes do fuzzer. Para serviços Java ou Rust, a lista de fuzzers pode estar vazia.