אפקט AIDL

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

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

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

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

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

כברירת מחדל, כלי ה-fuzzing נוצרים עם כיסוי.

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

SANITIZE_HOST=address SANITIZE_TARGET=hwaddress

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

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

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

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

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

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