אפקט AIDL

ה-fuzzer מתנהג כלקוח בשביל השירות המרוחק על ידי ייבוא או הפעלה שלו דרך ה-stub שנוצר:

באמצעות 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;
}

באמצעות 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);
});

מסגרת של שירותי fuzzing AIDL

כמו שאפשר לראות בדוגמה שלמעלה, ל-fuzzService יש קריאה ב-fuzzer והוא מקבל את IBinder (Service) ואת dataProvider כפרמטרים של קלט. קודם כול, מאתחלים אובייקט Parcel אקראי באמצעות ספק הנתונים, מפעילים את ה-method לביצוע טרנזקציה בשירות המרוחק באמצעות חבילת הקלט, ולבסוף מקבלים את התשובה לחבילת תשובה.

בנייה והפעלה של fuzzers

Fuzzers נוצרים עם כיסוי כברירת מחדל.

מומלץ להשתמש בחומרי החיטוי הבאים כדי לזהות בעיות בזיכרון. חומרי חיטוי של hwaddress פועלים רק בארכיטקטורה arm:

SANITIZE_HOST=address SANITIZE_TARGET=hwaddress

כשמריצים עם libFuzzer, ניתן לציין קורפוס, שהוא ספרייה, בקובץ Android.bp, ואפשר להעביר את הספרייה הזו ל-fuzzer. חלק מקובצי ה-fuzzer גם מציינים dictionary: בקובץ Android.bp, ואפשר להעביר אותו ל-libFuzzer באמצעות -dict path/to/dict. לאפשרויות נוספות, עיינו במסמכי התיעוד הרשמיים של libFuzzer.

כדי להריץ fuzzers במכשיר, מריצים את adb sync data ואז את adb shell data/fuzz/arch/name/name. כדי להריץ fuzzers במארח, מריצים את $ANDROID_HOST_OUT/fuzz/arch/name/name.

מערכת ה-build בודקת אם לכל שירות binder של AOSP יש רשומת fuzzer בקישורי fuzzer של שירותים. בבדיקת הקישור של Fuzzer, המערכת מוודאת שלכל שירות ב-service_contexts יש fuzzer. אם לא נמצאו fuzzer או חריגים בשירות חדש, נחשבת שגיאה ב-build.

אפשר לכתוב fuzzer אוטומטי של שירות C++ על ידי הוספת הקוד הבא (Java ו-Rust fuzzers עדיין לא נתמכים):

  • רשומת cc_fuzz ב-Android.bp להגדרת מודול fuzzer. במודול cc_default service_fuzzer_defaults יש יחסי תלות שנדרשים בשביל fuzzService.
  • יחסי תלות ספציפיים לשירות יש להוסיף כספרייה או כמקורות.
  • קובץ ראשי שיוצר את השירות ומבצע קריאה ל-fuzzService

להוראות מפורטות על השימוש ב-cc_fuzz, ראו Fuzzing with libFuzzer. כדי לפתור שגיאות build, מעדכנים את הקישורים לשירות החדש ולשמות של fuzzer. לשירותי Java או Rust, רשימת ה-fuzzer יכולה להיות ריקה.