Mô-đun tìm lỗi mã nguồn

Tính năng tìm lỗi mã nguồn Rust được hỗ trợ thông qua vùng chứa libfuzzer-sys. Vùng chứa này cung cấp các liên kết đến công cụ tìm lỗi mã nguồn libFuzzer của LLVM. Để biết thêm thông tin, hãy xem kho lưu trữ libfuzzer-sys cũng như trang dự án LLVM libFuzzer.

Mô-đun rust_fuzz tạo một tệp nhị phân của trình tạo dữ liệu ngẫu nhiên bắt đầu tạo dữ liệu ngẫu nhiên khi chạy (tương tự như các mô-đun cc_fuzz). Vì trình tìm lỗi mã nguồn sử dụng công cụ tìm lỗi mã nguồn libFuzzer, nên có thể cần một số đối số để kiểm soát việc tìm lỗi mã nguồn. Các loại lỗi này được liệt kê trong tài liệu về libFuzzer.

Mô-đun rust_fuzz là phần mở rộng của mô-đun rust_binary, do đó, mô-đun này có cùng các thuộc tính và điểm cần cân nhắc. Ngoài ra, các mô-đun này cũng triển khai nhiều thuộc tính và chức năng giống như các mô-đun cc_fuzz.

Khi tạo mô-đun rust_fuzz, cờ --cfg fuzzing sẽ được phát ra và có thể được dùng để hỗ trợ biên dịch có điều kiện của mã thư viện nhằm cải thiện tính năng tìm lỗi mã nguồn ngẫu nhiên.

Viết trình tìm lỗi mã nguồn Rust cơ bản

Bạn có thể xác định mô-đun tìm lỗi mã nguồn trong tệp bản dựng Android.bp bằng mã sau:

rust_fuzz {
    name: "example_rust_fuzzer",
    srcs: ["fuzzer.rs"],

    // Config for running the target on fuzzing infrastructure can be set under
    // fuzz_config. This shares the same properties as cc_fuzz's fuzz_config.
    fuzz_config: {
        fuzz_on_haiku_device: true,
        fuzz_on_haiku_host: false,
    },

    // Path to a corpus of sample inputs, optional. See https://llvm.org/docs/LibFuzzer.html#corpus
    corpus: ["testdata/*"],

    // Path to a dictionary of sample byte sequences, optional. See https://llvm.org/docs/LibFuzzer.html#dictionaries
    dictionary: "example_rust_fuzzer.dict",
}

Tệp fuzzer.rs chứa một trình tạo dữ liệu ngẫu nhiên đơn giản:

fn heap_oob() {
    let xs = vec![0, 1, 2, 3];
    let val = unsafe { *xs.as_ptr().offset(4) };
    println!("Out-of-bounds heap value: {}", val);
}

fuzz_target!(|data: &[u8]| {
    let magic_number = 327;
    if data.len() == magic_number {
        heap_oob();
    }
});

Ở đây, fuzz_target!(|data: &[u8]| { /* fuzz using data here */ }); xác định điểm truy cập mục tiêu làm rối mã nguồn do công cụ libFuzzer gọi. Đối số data là một trình tự byte do công cụ libFuzzer cung cấp để được thao tác dưới dạng dữ liệu đầu vào nhằm làm rối mã nguồn của hàm mục tiêu.

Trong trình tạo dữ liệu ngẫu nhiên mẫu này, chỉ kiểm tra độ dài của dữ liệu để xác định xem có gọi hàm heap_oob hay không, việc gọi hàm này sẽ dẫn đến việc đọc ngoài giới hạn. libFuzzer là một trình tạo dữ liệu ngẫu nhiên được hướng dẫn theo mức độ sử dụng, vì vậy, trình tạo này nhanh chóng hội tụ ở độ dài có vấn đề vì xác định rằng 326 B dữ liệu đầu tiên không dẫn đến đường dẫn thực thi mới.

Tìm ví dụ này trong cây thư mục tại tools/security/fuzzing/example_rust_fuzzer/. Để xem một ví dụ phức tạp hơn một chút về một trình tìm lỗi mã nguồn khác (tìm lỗi mã nguồn cho phần phụ thuộc rustlib) trong cây, hãy xem legacy_blob_fuzzer.

Để được hướng dẫn về cách viết trình tìm lỗi mã nguồn Rust có nhận biết cấu trúc, hãy xem sách Rust Fuzz, tài liệu chính thức cho dự án Rust Fuzz.