本指南假設您已建立要建構的模糊測試器。這份教學課程使用與該指南相同的程式碼範例。
Fuchsia 會使用 GN 這項元建構系統,產生 .ninja 檔案,明確說明如何建構系統。GN 目標是建構圖中的節點,代表特定輸出項目,例如程式庫或可執行檔。GN 範本是產生其他目標的規則。
為了讓新增新的模糊測試器變得更容易,Fuchsia 提供模糊測試相關的 GN 範本。
- 如要為 Fuchsia 的模糊測試器二進位檔建立建構規則,請參閱適當語言的 Fuchsia 程式庫模糊測試器 GN 範本。
- 如要為開發主機建立模糊測試二進位檔的建構規則,請參閱主機程式庫模糊測試 GN 範本
- 如要為模糊測試元件建立建構規則,請參閱 Fuchsia 模糊測試元件 GN 範本。
- 如要為 fuzzer 二進位檔套件建立建構規則,請參閱 Fuchsia fuzzer 套件 GN 範本。
定義建構規則後,您可以使用 fx 建構模糊測試器。
Fuchsia 程式庫模糊測試 GN 範本
每種語言都有特定的模糊測試 GN 範本:
C/C++
fuchsia_library_fuzzer GN 範本會產生 executable 目標,該目標會編譯並連結雜訊目標函式與測試中的程式碼和雜訊引擎。
如要為 C 或 C++ 模糊測試器建立建構規則,請將 fuchsia_library_fuzzer GN 目標新增至適當的 BUILD.gn,例如含有對應單元測試規則的 BUILD.gn。
例如:
import("//build/fuzz.gni")
fuchsia_library_fuzzer("parser-fuzzer") {
  sources = [ "parser_fuzzer.cc" ]
  deps = [ ":parser-lib" ]
}
荒漠油廠
rustc_fuzzer GN 範本會產生 GN 目標,將 Rust 模糊測試目標函式編譯為 C 物件檔案,然後連結至模糊測試引擎。
如要為 Rust 模糊測試器建立建構規則,請將 rustc_fuzzer GN 目標新增至 Crate 的 BUILD.gn。
選擇新增這個目標的位置和方式時,請考量下列事項:
- 建議您讓 fuzzer 名稱與 fuzz 目標函式名稱相符,並在 Rust 程式庫 (即 src/lib.rs) 中加入 fuzz 目標函式。您可以按照這些建議,將範本主體保留空白。舉例來說,如果您使用toy_example_arbitrary範例,請在BUILD.gn中新增下列內容:
import("//build/rust/rustc_fuzzer.gni")
rustc_fuzzer("toy_example_arbitrary") {
}
- 如果雜訊目標函式名稱與雜訊產生器名稱不同,您必須為其提供 rustfunction參數。舉例來說,如果您使用toy_example_u8範例,請在BUILD.gn中新增下列內容:
import("//build/rust/rustc_fuzzer.gni")
rustc_fuzzer("toy_example_raw_bytes") {
    rustfunction = "toy_example_u8"
}
- 如果要測試的程式碼無法輕鬆納入程式庫,您可以使用 Rust 二進位檔,並執行以下兩個額外步驟: 
- 您必須從編譯作業中排除 - main函式,以及在模糊測試時未使用的任何項目,例如僅在- main中使用的匯入項目。例如:- #[cfg(not(fuzz))] use only::used::in::main; #[cfg(not(fuzz))] fn main() { ... }
- 您必須使用 - source_root參數,明確將模糊測試目標函式提供給- rustc_fuzzer。例如,在- BUILD.gn中:- import("//build/rust/rustc_fuzzer.gni") rustc_fuzzer("toy_example_with_main") { source_root = "src/main.rs" }
選取模糊測試變數後,這些範本會將 [libFuzzer] 編譯器執行階段連結至提供的 sources、deps 或兩者,藉此建構模糊測試二進位檔。此程式碼必須提供模糊測試目標函式。
否則,您可以將測試套件與提供的程式碼連結,藉此建構模糊測試單元測試。這個測試架構會以固定的輸入內容 (例如長度為零的輸入內容) 呼叫模糊處理目標函式。這項測試可確保模糊測試器能夠編譯和連結,即使未針對模糊測試進行建構也一樣。
主機程式庫模糊測試 GN 範本
您也可以使用 Fuchsia 建構系統,建構在開發主機上執行的模糊測試工具。如要建構主機模糊測試工具,請使用 host_library_fuzzer GN 範本。
例如:
host_library_fuzzer("my_host_fuzzer") {
  sources = [ ... ]
  deps = [ ... ]
}
您可以使用 fx 建構主機雜訊測試工具,而無須將其新增至 Fuchsia 元件或套件。
Fuchsia 模糊測試元件的 GN 範本
fuchsia_fuzzer_component 範本會建立用於執行模糊測試的元件。可包含一般元件參數,例如 component_name 和 deps。
例如:
fuchsia_fuzzer_component("my-fuzzer-component") {
  component_name = "my-fuzzer"
  manifest = "meta/my-fuzzer.cml"
  deps = [ ":my-corpus"]
}
manifest 的程式庫模糊測試器必須包含 libfuzzer 的預設區塊。模糊測試器的輸出名稱必須以套件相對於路徑的形式,做為第一個程式引數提供。其他引數可能包括 libFuzzer 選項,或與套件相關的路徑,用於存放稱為種子語料庫的資料夾。
例如:
{
    include: [
        "//sdk/lib/inspect/client.shard.cml",
        "//src/sys/fuzzing/libfuzzer/default.shard.cml",
        "//src/sys/test_runners/fuzz/default.shard.cml",
        "//src/sys/test_runners/tmp_storage.shard.cml",
        "syslog/client.shard.cml",
    ]
    program: {
        args: [
            "test/my-fuzzer",
            "-max_input_size=256",
            "data/my-corpus",
        ]
    }
}
種子語料庫應與元件 deps 中包含的 resource 目標相符。
例如:
import("//build/dist/resource.gni")
resource("my-corpus") {
  sources = [
    "input0",
    "input1",
    "input2",
  ]
  outputs = [ "data/my-corpus/{{source_file_part}}" ]
}
Fuchsia 模糊測試器套件 GN 範本
fuchsia_fuzzer_package 範本會將 fuzzer 元件封裝到 Fuchsia 中。
  
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    fuchsia_test_packagefuchsia_fuzzer_package 範本的特色在於新增特定建構規則,以便在使用模糊測試工具鍊變化版本建構時,為模糊測試器加上註解。
範本包含參數,這些參數是根據語言排序的模糊測試元件清單。每種語言都有一組支援的消毒劑,由其工具鍊提供,做為編譯器執行階段。如果所選工具鍊變化版本包含特定語言支援的清理器,對應的模糊測試器元件清單就能進行模糊測試。
舉例來說,如果 C++ 工具鍊支援假設的 examplesan,而 Rust 工具鍊不支援,且選取 examplesan-fuzzer 變數,則下方的套件定義會建構 my-cpp-fuzzer 用於模糊測試,而 my-rust-fuzzer 則僅用於測試。
fuchsia_fuzzer_package("my-fuzzers") {
  cpp_fuzz_components = [ ":my-cpp-fuzzer" ]
  rust_fuzz_components = [ ":my-rust-fuzzer" ]
}
如果套件沒有使用對應語言編寫的模糊測試器,則不必納入清單。
fuchsia_fuzzer_package 可使用與 fuchsia_package 相同的所有參數。
例如:
fuchsia_fuzzer_package("my-fuzzers") {
  package_name = "the-fuzzers"
  cpp_fuzz_components = [ ":my-fuzzer" ]
}
定義完成後,套件就必須像其他測試套件一樣,納入建構依附元件圖表中。通常是指將測試加入一組測試。
例如:
group("tests") {
  deps = [
    ":my-test-package",
    ":my-fuzzers",
  ]
}
使用 fx 建構模糊測試器
如上所述,Fuchsia 建構系統「只會」在明確指示要使用適當的模糊測試變體對模糊測試進行檢測時,才會建構模糊測試程式。這些是結尾為 -fuzzer 的已知變體。每個擴充功能都是sanitizer 變體的擴充功能,包括:
- asan:使用 AddressSanitizer 偵測記憶體錯誤,例如在釋放或傳回記憶體後使用記憶體、堆積區和堆疊緩衝區溢位等。
- ubsan:使用 UndefinedBehaviorSanitizer 偵測違反語言規範的行為,例如有符號整數溢位、指標未對齊,以及更多。
如要建構含有模糊處理變化版本的 fuzzer_package,最簡單的方法就是使用 --fuzz-with <sanitizer> 旗標搭配 fx set。
例如:
fx set core.x64 --fuzz-with asan --with //bundles/testsfx build
執行 fx set 後,您可以使用 ffx fuzz list 查看目前已設定的模糊測試器。您可以使用其他 ffx fuzz 指令執行模糊測試器。