Mô-đun mờ

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. Những vấn đề này được liệt kê trong tài liệu libFuzzer.

Mô-đun rust_fuzz là phần mở rộng của các mô-đun rust_binary, nên sẽ chia sẻ các thuộc tính và điểm cần cân nhắc giống nhau. 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 xây dựng các mô-đun rust_fuzz, cờ --cfg fuzzing sẽ được phát ra, có thể dùng để hỗ trợ quá trình biên dịch có điều kiện của mã thư viện nhằm cải thiện hiệu suất mờ.

Viết một chương trình kiểm thử Rust cơ bản

Bạn có thể xác định mô-đun mờ trong tệp bản dựng Android.bp bằng mã này:

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 mờ 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ụ vào độ dài có vấn đề khi 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 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.

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