AIDL fuzzing

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

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

استفاده از 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 ، یک مجموعه کد (corpus) که یک دایرکتوری است، ممکن است در فایل Android.bp مشخص شود و شما می‌توانید این دایرکتوری را به fuzzer ارسال کنید. برخی از fuzzerها همچنین یک dictionary: در فایل Android.bp خود مشخص می‌کنند و شما می‌توانید آن را با استفاده از -dict path/to/dict ‎ به libFuzzer ارسال کنید. برای گزینه‌های بیشتر، به مستندات رسمی libFuzzer مراجعه کنید.

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

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

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

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

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