AIDL-фаззинг

Фаззер ведет себя как клиент для удаленной службы, импортируя или вызывая ее через сгенерированную заглушку:

Использование 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;
}

Использование 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);
});

Фреймворк для фаззинга служб AIDL

Как показано в примере выше, fuzzService вызывается в фаззере и принимает IBinder (Service) и dataProvider в качестве входных параметров. Сначала он инициализирует случайный объект Parcel с помощью поставщика данных и вызывает метод transact на удаленной службе с помощью входного пакета, и, наконец, получает ответ в ответном пакете.

Создание и запуск фаззеров

Фаззеры изначально созданы с покрытием.

Для обнаружения проблем с памятью рекомендуются следующие санитайзеры. Санатории hwaddress работают только на архитектуре arm :

SANITIZE_HOST=address SANITIZE_TARGET=hwaddress

При запуске с libFuzzer корпус, который является каталогом, может быть указан в файле Android.bp , и вы можете передать этот каталог фаззеру. Некоторые фаззеры также указывают dictionary: в своем файле Android.bp , и вы можете передать его в libFuzzer с помощью -dict path/to/dict . Дополнительные параметры см. в официальной документации libFuzzer .

Чтобы запустить фаззеры на устройстве, запустите adb sync data , а затем adb shell data/fuzz/ arch / name / name . Чтобы запустить фаззеры на хосте, запустите $ANDROID_HOST_OUT/ fuzz / arch / name / name .

Система сборки проверяет, есть ли у каждой службы AOSP binder запись fuzzer в service fuzzer bindings . Тест привязки Fuzzer проверяет, есть ли у каждой службы в service_contexts fuzzer. Если для новой службы не найден fuzzer или исключение, возникает ошибка сборки.

Автоматический фаззер сервиса C++ можно написать, добавив следующее (фаззеры Java и Rust пока не поддерживаются):

  • Запись cc_fuzz в Android.bp для определения модуля fuzzer. Модуль cc_default service_fuzzer_defaults имеет зависимости, необходимые для fuzzService .
  • Зависимости, специфичные для сервиса, следует добавлять в виде библиотеки или источников.
  • Основной файл, который создает вашу службу и вызывает fuzzService

Подробные инструкции по использованию cc_fuzz см. в документации Fuzzing with libFuzzer . Чтобы устранить ошибку сборки, обновите привязки с новыми именами сервиса и fuzzer. Для сервисов Java или Rust список fuzzer может быть пустым.