Fuzzing AIDL

Fuzzer berperilaku sebagai klien untuk layanan jarak jauh dengan mengimpor atau memanggilnya melalui stub yang dihasilkan:

Menggunakan C++ API:

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

Menggunakan Rust API:

#![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 untuk menguji layanan AIDL

Seperti yang ditunjukkan pada contoh di atas, fuzzService dipanggil di fuzzer dan menggunakan IBinder (Service) dan dataProvider sebagai parameter input. Pertama-tama, kode ini menginisialisasi objek Parcel acak menggunakan penyedia data dan memanggil metode transaksi pada layanan jarak jauh menggunakan paket input, dan terakhir mendapatkan balasan ke dalam paket balasan.

Membangun dan menjalankan fuzzers

Fuzzer dibuat dengan cakupan secara default.

Sanitizer berikut direkomendasikan untuk menemukan masalah memori. Sanitizer hwaddress hanya berjalan pada arsitektur arm:

SANITIZE_HOST=address SANITIZE_TARGET=hwaddress

Saat berjalan dengan libFuzzer, korpus, yang merupakan direktori, dapat ditentukan dalam file Android.bp, dan Anda dapat meneruskan direktori ini ke fuzzer. Beberapa fuzzer juga menentukan dictionary: dalam file Android.bp, dan Anda dapat meneruskannya ke libFuzzer dengan -dict path/to/dict. Untuk opsi lainnya, lihat dokumentasi libFuzzer resmi.

Untuk menjalankan fuzzer di perangkat, jalankan adb sync data, lalu adb shell data/fuzz/arch/name/name. Untuk menjalankan fuzzer di host, jalankan $ANDROID_HOST_OUT/fuzz/arch/name/name.

Sistem build memeriksa apakah setiap layanan binder AOSP memiliki entri fuzzer di binding fuzzer layanan. Pengujian binding Fuzzer memeriksa bahwa setiap layanan di service_contexts memiliki fuzzer. Jika fuzzer atau pengecualian tidak ditemukan untuk layanan baru, akan terjadi error build.

Fuzzer layanan C++ otomatis dapat ditulis dengan menambahkan berikut ini (fuzzer Java dan Rust belum didukung):

  • Entri cc_fuzz di Android.bp untuk menentukan modul fuzzer. Modul cc_default service_fuzzer_defaults memiliki dependensi yang diperlukan untuk fuzzService.
  • Dependensi khusus layanan harus ditambahkan sebagai library atau sebagai sumber.
  • File utama yang membangun layanan Anda dan memanggil fuzzService

Untuk petunjuk mendetail tentang penggunaan cc_fuzz, lihat dokumentasi Fuzzing dengan libFuzzer. Untuk mengatasi error build, perbarui binding dengan nama layanan dan fuzzer baru. Untuk layanan Java atau Rust, daftar fuzzer dapat kosong.