Tìm lỗi mã nguồn AIDL

Trình kiểm thử fuzz hoạt động như một ứng dụng cho dịch vụ từ xa bằng cách nhập hoặc gọi dịch vụ đó thông qua phần giữ chỗ đã tạo:

Sử dụng 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;
}

Sử dụng 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);
});

Khung để kiểm thử ngẫu nhiên các dịch vụ AIDL

Như trong ví dụ trên, fuzzService được gọi trong trình kiểm thử ngẫu nhiên và nhận IBinder (Dịch vụ) và dataProvider làm tham số đầu vào. Trước tiên, phương thức này sẽ khởi tạo một đối tượng Parcel ngẫu nhiên bằng cách sử dụng trình cung cấp dữ liệu và gọi phương thức giao dịch trên dịch vụ từ xa bằng cách sử dụng gói đầu vào, sau đó cuối cùng nhận được câu trả lời vào một gói phản hồi.

Tạo và chạy trình kiểm thử lỗi

Theo mặc định, các fuzzers được tạo bằng độ bao phủ.

Bạn nên dùng các trình dọn dẹp sau đây để phát hiện các vấn đề về bộ nhớ. Các trình dọn dẹp hwaddress chỉ chạy trên cấu trúc arm:

SANITIZE_HOST=address SANITIZE_TARGET=hwaddress

Khi chạy với libFuzzer, bạn có thể chỉ định một tập hợp (là một thư mục) trong tệp Android.bp và bạn có thể truyền thư mục này đến trình kiểm thử lỗi. Một số trình kiểm thử fuzz cũng chỉ định dictionary: trong tệp Android.bp và bạn có thể truyền tệp này đến libFuzzer bằng -dict path/to/dict. Để biết thêm các lựa chọn khác, hãy xem tài liệu chính thức về libFuzzer.

Để chạy fuzzers trên thiết bị, hãy chạy adb sync data rồi chạy adb shell data/fuzz/arch/name/name. Để chạy fuzzers trên máy chủ lưu trữ, hãy chạy $ANDROID_HOST_OUT/fuzz/arch/name/name.

Hệ thống xây dựng sẽ kiểm tra xem mọi dịch vụ liên kết AOSP có mục trình kiểm tra lỗi ngẫu nhiên trong các liên kết trình kiểm tra lỗi ngẫu nhiên của dịch vụ hay không. Kiểm thử liên kết Fuzzer kiểm tra để đảm bảo rằng mọi dịch vụ trong service_contexts đều có một fuzzer. Nếu không tìm thấy trình kiểm thử lỗi hoặc trường hợp ngoại lệ cho một dịch vụ mới, thì sẽ xảy ra lỗi bản dựng.

Bạn có thể viết một trình kiểm thử lỗi tự động cho dịch vụ C++ bằng cách thêm nội dung sau (chưa hỗ trợ trình kiểm thử lỗi Java và Rust):

  • Một mục cc_fuzz trong Android.bp để xác định mô-đun fuzzer. Mô-đun cc_default service_fuzzer_defaults có các phần phụ thuộc bắt buộc đối với fuzzService.
  • Bạn nên thêm các phần phụ thuộc dành riêng cho dịch vụ dưới dạng thư viện hoặc nguồn.
  • Một tệp chính tạo nên dịch vụ của bạn và gọi fuzzService

Để biết hướng dẫn chi tiết về cách sử dụng cc_fuzz, hãy xem tài liệu Fuzzing with libFuzzer (Fuzzing bằng libFuzzer). Để giải quyết lỗi bản dựng, hãy cập nhật các liên kết bằng dịch vụ và tên trình kiểm thử fuzz mới. Đối với các dịch vụ Java hoặc Rust, danh sách trình kiểm thử fuzz có thể trống.