تست فازینگ AIDL

«فازر» با وارد کردن یا فراخواندن سرویس از دور ازطریق میانای تولیدشده، به‌عنوان کارخواه سرویس از دور عمل می‌کند:

استفاده از 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;
}

استفاده از 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);
});

چارچوب برای فازینگ سرویس‌های AIDL

همان‌طور که در مثال بالا نشان داده شده است، fuzzService در fuzzzer فراخوانده می‌شود و IBinder (سرویس) و dataProvider را به‌عنوان پارامترهای ورودی می‌گیرد. ابتدا بااستفاده از ارائه‌دهنده داده یک شیء Parcel تصادفی را مقداردهی اولیه می‌کند و بااستفاده از بسته ورودی، روش transact را در سرویس راه دور فرا می‌خواند و درنهایت پاسخ را در بسته پاسخ دریافت می‌کند.

ساختن و اجرای fuzzers

به‌طور پیش‌فرض، fuzzers با پوشش ساخته می‌شوند.

برای کشف مشکلات حافظه، پاک‌کننده‌های زیر توصیه می‌شود. hwaddress پاک‌کننده فقط در معماری arm اجرا می‌شود:

SANITIZE_HOST=address SANITIZE_TARGET=hwaddress

هنگام اجرا با libFuzzer، پیکره‌ای که یک دایرکتوری است ممکن است در فایل Android.bp مشخص شود و می‌توانید این دایرکتوری را به فازر منتقل کنید. برخی‌از فازرها همچنین dictionary: را در فایل Android.bp خود مشخص می‌کنند و می‌توانید آن را با -dict path/to/dict به libFuzzer ارسال کنید. برای گزینه‌های بیشتر، اسناد رسمی libFuzzer را ببینید.

برای اجرای fuzzers در دستگاه، adb sync data و سپس adb shell data/fuzz/arch/name/name را اجرا کنید. برای اجرای fuzzers در میزبان، $ANDROID_HOST_OUT/fuzz/arch/name/name را اجرا کنید.

سیستم ساخت بررسی می‌کند که آیا هر سرویس متصل‌کننده AOSP دارای ورودی فازر در اتصال‌های فازر سرویس است یا نه. آزمایش پیوند Fuzzer بررسی می‌کند که هر سرویس در service_contexts یک fuzzer داشته باشد. اگر برای سرویس جدیدی فازر یا استثنایی پیدا نشود، خطای ساخت وجود دارد.

با افزودن موارد زیر می‌توان یک سرویس C++ fuzzing خودکار نوشت (از fuzzing جاوا و Rust هنوز پشتیبانی نمی‌شود):

  • یک ورودی cc_fuzz در Android.bp برای تعریف کردن واحد فازر. واحد cc_default service_fuzzer_defaults وابستگی‌هایی دارد که برای fuzzService لازم است.
  • وابستگی‌های مختص سرویس باید به‌عنوان کتابخانه یا به‌عنوان منبع اضافه شوند.
  • فایل اصلی که سرویس شما را می‌سازد و fuzzService را فرا می‌خواند

برای دستورالعمل‌های دقیق درباره استفاده از cc_fuzz، به سند Fuzzing with libFuzzer مراجعه کنید. برای رفع خطای ساخت، پیوندها را با نام‌های سرویس و فازر جدید به‌روز کنید. برای سرویس‌های Java یا Rust، فهرست فازر می‌تواند خالی باشد.