El generador de fuzz se comporta como un cliente del servicio remoto, ya que lo importa o lo invoca a través del stub generado:
Si usas la API de 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;
}
Con la API de 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 fuzzing de servicios de AIDL
Como se muestra en el ejemplo anterior, Servicio fuzzi se llama en el fuzzer y recibe un IBinder (Service) y dataProvider como parámetros de entrada. Primero inicializa un objeto Parcel aleatorio usando los datos y llamar al método de transacción en el servicio remoto mediante la entrada paquete y, por último, recibirás la respuesta en un paquete de respuesta.
Crea y ejecuta fuzzers
Los fuzzers se crean con cobertura de forma predeterminada.
Se recomiendan los siguientes validadores para descubrir problemas de memoria.
Los validadores de hwaddress
solo se ejecutan en la arquitectura arm
:
SANITIZE_HOST=address SANITIZE_TARGET=hwaddress
Cuando se ejecuta con libFuzzer
, se puede especificar un corpus, que es un directorio
en el archivo Android.bp
, y puedes pasar este directorio al fuzzer. Algunos generadores de fuzz también especifican un dictionary:
en su archivo Android.bp
, y puedes pasarlo a libFuzzer con -dict path/to/dict
. Para ver más opciones, consulta la documentación oficial de libFuzzer.
Para ejecutar generadores de fuzz en el dispositivo, ejecuta adb sync data
y, luego, adb shell data/fuzz/arch/name/name
.
Para ejecutar fuzzers en el host, ejecuta
$ANDROID_HOST_OUT/fuzz/arch/name/name
Cómo recomendar fuzzers para servicios nuevos o existentes
El sistema de compilación verifica si cada servicio de Binder de AOSP tiene una entrada de generador de fuzz en los vinculaciones de generador de fuzz de servicio.
La prueba de vinculación de Fuzzer verifica que todos los servicios de service_contexts
tengan un
fuzzer. Si no se encuentra un generador de fuzz o una excepción para un servicio nuevo, hay un error de compilación.
Se puede escribir un fuzzer automático del servicio C++ agregando lo siguiente (Java y Los fuzzers de Rust aún no son compatibles):
- Una entrada
cc_fuzz
enAndroid.bp
para definir el módulo de generador de fuzz. El módulocc_default
service_fuzzer_defaults
tiene dependencias requeridas parafuzzService
. - Las dependencias específicas del servicio deben agregarse como bibliotecas o como fuentes.
- Un archivo principal que construye tu servicio y llama a
fuzzService
Para obtener instrucciones detalladas sobre el uso de cc_fuzz
, consulta la documentación sobre Fuzzing con libFuzzer. Para resolver el error de compilación, actualiza las vinculaciones con el nuevo servicio y
del fuzzer. En el caso de los servicios de Java o Rust, la lista de fuzzers puede estar vacía.