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 melakukan fuzz pada layanan AIDL

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

Mem-build dan menjalankan fuzzer

Fuzzer dibuat dengan cakupan secara default.

Sanitizer berikut direkomendasikan untuk menemukan masalah memori. Pembersih hwaddress hanya berjalan di 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 ada error build.

Fuzzer layanan C++ otomatis dapat ditulis dengan menambahkan hal berikut (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 membuat layanan Anda dan memanggil fuzzService

Untuk petunjuk mendetail tentang cara menggunakan 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.