fuzzing: add generic TLV custom mutator with harnesses#1455
fuzzing: add generic TLV custom mutator with harnesses#1455
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #1455 +/- ##
=======================================
Coverage 91.80% 91.80%
=======================================
Files 37 37
Lines 4282 4282
Branches 524 524
=======================================
Hits 3931 3931
Misses 260 260
Partials 91 91
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
This PR adds a reusable, grammar-aware TLV custom mutator for libFuzzer and introduces two new fuzzing harnesses targeting TLV “Trusted Name” and “Dynamic Descriptor” parsing use cases, along with build-system and documentation updates to integrate them into the SDK fuzzing setup.
Changes:
- Add a generic TLV custom mutator (
tlv_mutator.c/.h) driven by a per-harness tag grammar. - Add two new TLV fuzzing harnesses plus shared PKI-signature-bypass mocks.
- Extend fuzzing CMake and README to build/run the new fuzzers and document TLV mutator usage.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| fuzzing/libs/lib_tlv.cmake | Expands TLV library sources and link/include dependencies for fuzzing. |
| fuzzing/harness/tlv_mutator.h | Declares the generic TLV mutator configuration interface for harnesses. |
| fuzzing/harness/tlv_mutator.c | Implements the TLV grammar-aware libFuzzer custom mutator. |
| fuzzing/harness/fuzzer_tlv_trusted_name.c | Adds a TLV harness + grammar for the Trusted Name use case. |
| fuzzing/harness/fuzzer_tlv_dynamic_descriptor.c | Adds a TLV harness + grammar for the Dynamic Descriptor use case. |
| fuzzing/harness/fuzz_tlv_common_mocks.c | Adds shared mocks to bypass PKI signature verification during fuzzing. |
| fuzzing/extra/lib_tlv_trusted_name.cmake | Adds CMake target to build the Trusted Name TLV fuzzer. |
| fuzzing/extra/lib_tlv_dynamic_descriptor.cmake | Adds CMake target to build the Dynamic Descriptor TLV fuzzer. |
| fuzzing/README.md | Documents TLV fuzzing and lists new fuzzers in run instructions. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| include(${BOLOS_SDK}/fuzzing/mock/mock.cmake) | ||
|
|
||
| file(GLOB LIB_TLV_SOURCES "${BOLOS_SDK}/lib_tlv/*.c") | ||
| file(GLOB LIB_TLV_SOURCES "${BOLOS_SDK}/lib_tlv/*.c" "${BOLOS_SDK}/lib_tlv/use_cases/*.c") |
There was a problem hiding this comment.
file(GLOB ...) now pulls in all lib_tlv/use_cases/*.c into the tlv library. At least tlv_use_case_dynamic_descriptor.c requires APPNAME to be defined at compile time; building any target that links tlv (e.g., fuzz_tlv_trusted_name) will fail unless APPNAME is provided for the tlv target. Consider compiling use-case sources into the specific fuzzer executable instead of the shared tlv library, or add guarded defaults / per-use-case compile definitions.
| file(GLOB LIB_TLV_SOURCES "${BOLOS_SDK}/lib_tlv/*.c" "${BOLOS_SDK}/lib_tlv/use_cases/*.c") | |
| file(GLOB LIB_TLV_SOURCES "${BOLOS_SDK}/lib_tlv/*.c") |
There was a problem hiding this comment.
@0pendev wdyt? We might want to split the tlv usecase lib from the tlv parser itself. Or do we just add a guard but in this case some features might just only rely on the TLV parser without providing a APPNAME.
| include(${BOLOS_SDK}/fuzzing/mock/mock.cmake) | ||
|
|
||
| file(GLOB LIB_TLV_SOURCES "${BOLOS_SDK}/lib_tlv/*.c") | ||
| file(GLOB LIB_TLV_SOURCES "${BOLOS_SDK}/lib_tlv/*.c" "${BOLOS_SDK}/lib_tlv/use_cases/*.c") |
There was a problem hiding this comment.
@0pendev wdyt? We might want to split the tlv usecase lib from the tlv parser itself. Or do we just add a guard but in this case some features might just only rely on the TLV parser without providing a APPNAME.
| ```console | ||
|
|
||
| ```c | ||
| int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { | ||
| if (sigsetjmp(fuzz_exit_jump_ctx.jmp_buf, 1)) return 0; | ||
|
|
||
| ### harness code ### | ||
|
|
||
| return 0; | ||
| /* harness code */ | ||
| return 0; | ||
| } | ||
|
|
||
| ``` | ||
|
|
||
| This allows a return point when the `os_sched_exit()` function is mocked. | ||
|
|
||
| - To provide an SDK interface, we automatically generate syscall mock functions located in |
There was a problem hiding this comment.
Why did we remove this part?
There was a problem hiding this comment.
I removed that snippet becasue none of the current harnesses in fuzzing/harness use sigsetjmp / fuzz_exit_jump_ctx, and fuzz_exit_jump_ctx is not defined anywhere anymore.
|
Also, we must make the CI green :) |
c599532 to
4f7ac7f
Compare
Description
Add a TLV custom mutator (
tlv_mutator.c) for libFuzzer that generatesvalid TLV messages with 6 mutation strategies: build, append, delete, duplicate,
corrupt length, and truncate.
Add two harnesses for TLV use cases:
fuzzer_tlv_trusted_name.c)fuzzer_tlv_dynamic_descriptor.c)The mutator is use-case agnostic: each harness defines its own tag grammar via a
tlv_tag_info_tarray, making it reusable for any future TLV-based fuzzing target.Changes include
Auto cherry-pick in API_LEVEL
If requested to port the commits from this PR on a dedicated API_LEVEL branch,
select the targeted one(s), or add new references if not listed:
[ ] TARGET_API_LEVEL: API_LEVEL_25
This will only create the PR with cherry-picks, ready to be reviewed and merged.
Remember: