Fuzzing AIDL

El fuzzer se comporta como un cliente para el servicio remoto importándolo/invocándolo a través del código auxiliar generado:

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

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

Usando la API de Java:

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

Para la configuración de compilación, consulte Java Binder Service Fuzzer .

Marco para difuminar los servicios AIDL

Como se muestra en el ejemplo anterior, se llama a fuzzService en el fuzzer y toma un IBinder (servicio) y un proveedor de datos como parámetros de entrada. Primero inicializa un objeto Parcel aleatorio utilizando el proveedor de datos y llama al método de transacción en el servicio remoto utilizando el paquete de entrada y, finalmente, obtiene la respuesta en un paquete de respuesta.

El sistema de compilación comprueba si cada servicio de carpeta AOSP tiene una entrada de fuzzer en los enlaces de fuzzer de servicio . La prueba de enlace de Fuzzer comprueba que cada servicio en service_contexts tenga un fuzzer. Si no se encuentra un fuzzer/excepción para un nuevo servicio, hay un error de compilación.

Se puede escribir un fuzzer de servicio C++ automático agregando lo siguiente (los fuzzers de Java y Rust aún no son compatibles):

  • Una entrada cc_fuzz en Android.bp para definir el módulo fuzzer. El módulo cc_default service_fuzzer_defaults tiene dependencias necesarias para fuzzService .
  • Las dependencias específicas del servicio deben agregarse como biblioteca o como fuentes.
  • Un archivo principal que construye su servicio y llama fuzzService

Para obtener instrucciones detalladas sobre el uso cc_fuzz , consulte la documentación Fuzzing con libFuzzer . Para resolver el error de compilación, actualice los enlaces con los nuevos nombres de servicio y fuzzer. Para los servicios Java/Rust, la lista de fuzzer puede estar vacía.