การทดสอบ AIDL แบบ Fuzzing

Fuzzer จะทำงานเป็นไคลเอ็นต์สำหรับบริการระยะไกลโดยการนำเข้าหรือเรียกใช้ผ่าน Stub ที่สร้างขึ้น

การใช้ 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 จะเรียกใช้ใน Fuzzer และรับ IBinder (Service) และ dataProvider เป็น พารามิเตอร์อินพุต โดยจะเริ่มต้นด้วยการเริ่มต้นออบเจ็กต์ Parcel แบบสุ่มโดยใช้ data provider และเรียกเมธอด transact ในบริการระยะไกลโดยใช้ input parcel และสุดท้ายรับการตอบกลับลงใน reply parcel

สร้างและเรียกใช้ Fuzzer

Fuzzer สร้างขึ้นโดยมีการครอบคลุมโดยค่าเริ่มต้น

เราขอแนะนำให้ใช้ Sanitizer ต่อไปนี้เพื่อค้นหาปัญหาเกี่ยวกับหน่วยความจำ hwaddress Sanitizer จะทำงานในสถาปัตยกรรม arm เท่านั้น

SANITIZE_HOST=address SANITIZE_TARGET=hwaddress

เมื่อเรียกใช้ด้วย libFuzzer คุณอาจระบุคลังข้อความซึ่งเป็นไดเรกทอรี ในไฟล์ Android.bp และส่งไดเรกทอรีนี้ไปยัง Fuzzer ได้ Fuzzer บางตัวยังระบุ dictionary: ในไฟล์ Android.bp ด้วย และคุณสามารถส่งผ่านไปยัง libFuzzer ด้วย -dict path/to/dict ได้ ดูตัวเลือกเพิ่มเติมได้ในเอกสารประกอบอย่างเป็นทางการของ libFuzzer

หากต้องการเรียกใช้ Fuzzer ในอุปกรณ์ ให้เรียกใช้ adb sync data แล้ว adb shell data/fuzz/arch/name/name หากต้องการเรียกใช้ Fuzzer ในโฮสต์ ให้เรียกใช้ $ANDROID_HOST_OUT/fuzz/arch/name/name

ระบบบิลด์จะตรวจสอบว่าบริการ Binder ของ AOSP ทุกรายการมีรายการ Fuzzer ใน การเชื่อมโยง Fuzzer ของบริการหรือไม่ การทดสอบการเชื่อมโยง Fuzzer จะตรวจสอบว่าทุกบริการใน service_contexts มี Fuzzer หากไม่พบ Fuzzer หรือข้อยกเว้นสำหรับบริการใหม่ จะเกิดข้อผิดพลาดในการสร้าง

คุณเขียน Fuzzer บริการ C++ อัตโนมัติได้โดยเพิ่มข้อมูลต่อไปนี้ (ระบบยังไม่รองรับ Fuzzer Java และ Rust)

  • cc_fuzz ใน Android.bp เพื่อกำหนดโมดูล Fuzzer cc_default โมดูล service_fuzzer_defaults มีการขึ้นต่อกันที่จำเป็นสำหรับ fuzzService
  • ควรเพิ่มการอ้างอิงเฉพาะบริการเป็นไลบรารีหรือเป็นแหล่งที่มา
  • ไฟล์หลักที่สร้างบริการและเรียกใช้ fuzzService

ดูวิธีการโดยละเอียดเกี่ยวกับการใช้ cc_fuzz ได้ในเอกสารประกอบการฟัซด้วย libFuzzer หากต้องการแก้ไขข้อผิดพลาดในการสร้าง ให้อัปเดตการเชื่อมโยงด้วยชื่อบริการและ Fuzzer ใหม่ สำหรับบริการ Java หรือ Rust รายการ Fuzzer อาจว่างเปล่าได้