Core Workflow
用户输入需求
↓
[决策点] 用户意图是什么?
├─ 给类名要求生成测试 → 进入完整工作流
├─ 给现有文件要求检查 → 跳至阶段 5(规范审查)
├─ 要求生成种子 → 跳至阶段 4(种子语义生成)
└─ 要求生成报告 → 跳至阶段 5 后生成报告
↓
[阶段 1] 代码分析 —— 解析目标 API 类结构、方法签名、参数类型
↓
[阶段 2] 骨架生成 —— 创建 5 文件标准化工程(.cpp/.h/BUILD.gn/project.xml/corpus)
↓
[阶段 3] 实现填充 —— 模板替换为实际 API 职责与数据构造逻辑
↓
[阶段 4] 种子语义生成 —— 基于参数类型/名称特征生成高价值初始 corpus
↓
[阶段 5] 规范审查 —— 26 条规则逐一验证,输出合规报告
**加载触发**:仅加载违规规则的 rules/SecurityCodeReview_FuzzCheck_XXX.md
**必须加载**:规则 005 详细说明(复杂参数构造,误报高发区)
**不要加载**:未违规规则、规则速查表(`references/rules-overview.md` 仅在审查时加载)
↓
[阶段 6] 自动修复 —— 可自动修复规则执行修复(最多 3 轮)
↓
交付生成文件 + 审查报告 + 人工确认项清单
Exception Handling Decision Tree:
- Stage 1 parsing failure (class/header file not found) → check class name spelling → provide header file path → manual parsing
- Stage 5 finds violations that cannot be automatically fixed → output manual fix guide → mark BLOCK → skip fixing
- Stage 6 still fails after 3 rounds of fixing → stop fixing → output list of remaining violations → recommend manual review
Tool Entry Points
| Tool | Purpose | Command Example |
|---|---|---|
tools/fuzz_generator.py |
Generate FUZZ test cases | python tools/fuzz_generator.py -n XxxXxx_fuzzer -N Namespace -c ClassName -H header.h -p output_path |
tools/fuzz_check.py |
Specification review (26 rules) | python tools/fuzz_check.py --dir fuzzer_dir [--fix] |
tools/seed_generator.py |
Generate semantic seeds | python tools/seed_generator.py --dir fuzzer_dir [--api ApiName] |
tools/generate_report.py |
Generate compliance report | python tools/generate_report.py --dir fuzzer_dir |
Key Decisions
Self-check Before Generation
Before starting generation, first confirm:
- Does the target API have parameters? No parameters → refuse to generate, recommend unit testing (Rule 001)
- Is it an IPC interface? Inherits
IRemoteBroker/ containsDECLARE_INTERFACE_DESCRIPTOR→ must generate an IPC stub fuzzer (LLVMFuzzerInitializeinitialize globalg_stub,LLVMFuzzerTestOneInputusecode % CODE_MAXto drive),sptr<T>parameters written toWriteRemoteObject(nullptr)(Rule 007) - Number of interfaces in a single file? >10 → split into multiple fuzzers (Rule 006)
- Are all parameters output types? Non-const references/pointers → skip, no fuzz input needed
Type Mapping Decisions
| Type Category | Consumption Code | Description |
|---|---|---|
| Identifier types (UpperCamelCase non-enum) | fdp.ConsumeIntegral<uint64_t>() |
such as ScreenId/NodeId, underlying is uint64_t typedef |
| Process/user identifiers | fdp.ConsumeIntegral<uint32_t>() |
such as ProcessId/Uid |
| File descriptors | fdp.ConsumeIntegral<int32_t>() |
such as Fd |
| Enum types | static_cast<EnumType>(fdp.ConsumeIntegral<uint8_t>() % ENUM_SIZE) |
Must use uint8_t(Rule 013) |
| Strings | fdp.ConsumeRandomLengthString(256) |
Limit maximum length to prevent memory explosion |
| Containers | First consume length uint8_t count = fdp.ConsumeIntegral<uint8_t>() % 32, then consume in a loop |
Applicable to std::vector<T> |
Key distinction: UpperCamelCase naming is not necessarily an enum; it may be a typedef alias. Must check ENUM_SIZE_MAP to confirm whether it is an enum.
Unknown Type Handling Strategy:
- Type is in
TYPE_CONSUMER_MAP→ use the mapping directly - Type is not in the mapping but is UpperCamelCase → check
ENUM_SIZE_MAP→ if it is an enum thenuint8_t % ENUM_SIZE - Type is not in the mapping and is not UpperCamelCase → check whether it is
std::vector<T>→ if so, consume in a loop - None of the above match → Must load
tools/fuzz_generator.pyto inspectCOMPLEX_TYPE_MAPor construct custom consumption logic
NEVER List
- NEVER Use
rand()/random()—— not reproducible, losing the significance of coverage tracking (Rule 017) - NEVER Set
sizePass parameters as mutation data to the API — the fuzz engine cannot effectively mutate the length (Rule 010) - NEVER Directly dereference
datapointer — may contain an illegal address, 100% triggers SIGSEGV (Rule 018) - NEVER Use an uninitialized global pointer — the fuzz engine will misjudge it as a stable crash and stop exploring (Rule 019)
- NEVER Generate FUZZ for an API with no parameters — coverage will always be 0 (Rule 001)
- NEVER Test more than 10 interfaces in a single file — insufficient mutation budget, coverage decreases (Rule 006)
- NEVER Use
autoto declare fuzz variables — type matching cannot be manually verified (Rule 016) - NEVER Skip the Verify loop — state machine-related bugs (resource leaks, order dependencies) cannot be found
- NEVER Use
uint32_tfor enums — 1-byte mutation is far more efficient than 4-byte (Rule 013)
References
Load on demand according to the task:
-
references/rules-overview.md— Quick reference table of 26 rules (name/severity/automatic check/automatic fix)- When to load: only during Phase 5 specification review
- Do not load: generation phase
-
rules/SecurityCodeReview_FuzzCheck_XXX.md— Detailed description of violated rules (correct and incorrect examples + exemption conditions)- When to load: when a violation is found during Phase 5 specification review
- Do not load: rules that are not violated
-
rules/SecurityCodeReview_FuzzCheck_005.md— Detailed explanation of complex parameter construction rules- When to load: when struct/pointer/callback/container parameters are involved
- Reason: Rule 005 is a high-incidence area for false positives, exemption conditions need to be carefully checked
-
tools/fuzz_generator.py— Test case generator source code- When to load: when you need to understand the generation logic or customize type mapping
- Key things to check:
TYPE_CONSUMER_MAP、ENUM_SIZE_MAP、COMPLEX_TYPE_MAP
-
templates/fuzzer.cpp— Code generation template- When to load: when you need to customize the fuzzer code structure
- Do not load: when using the generator normally
Official documentation:
- OpenHarmony Fuzz Testing Specification — https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/test/fuzz-test.md
- LLVM LibFuzzer Official Documentation — https://llvm.org/docs/LibFuzzer.html
- FuzzedDataProvider API — https://llvm.org/docs/LibFuzzer.html#fuzzed-data-provider