This repository documents a 10-day fuzzing campaign targeting libucl, a universal configuration language library. The goal was to explore the parser and schema validation logic using libFuzzer with sanitizers and custom harnesses.
fuzzing-campaign-1/
├── fuzz.sh # Build + fuzz orchestration script
├── fuzz\_validation.c # Custom libFuzzer harness for schema + object validation
├── main\_tester.c # Minimal repro driver (ASan/UBSan enabled)
├── triage.sh # Crash triage script
├── ucl.dict # libFuzzer dictionary (tokens & keywords)
├── validation\_corpus/ # Seed inputs
├── writeup.md # This writeup
The fuzzing harnesses use clang, libFuzzer, and AddressSanitizer (ASan).
To rebuild everything:
./fuzz.sh buildThis:
- Rebuilds libucl with sanitizers
- Compiles fuzz targets (
fuzz_ucl_parser,repro_min) - Compiles a standalone tester (
main_tester)
Default run:
./fuzz.sh fuzzThis runs fuzz_ucl_parser with:
-fork=8(parallel workers)-ignore_crashes=1-use_value_profile=1seed_corpus/(initial seeds)ucl.dict(custom tokens)
Additional options can be passed directly, for example:
./fuzz.sh fuzz -max_total_time=3600After fuzzing, inputs are replayed against main_tester and categorized:
./triage.sh <input>[CRASH]→ Real bug (ASan/UBSan triggered, saved underartifacts/)[PARSE ERROR]→ Expected parse failure (discarded)[OK]→ Valid input
- Splits input in half → one half as a schema, one half as an object
- Applies depth and node count limits to prevent runaway recursion
- Validates objects against schema with
ucl_object_validate - Protects against
SIGSEGV,SIGBUS,SIGILLusingsigsetjmp
Optional modes:
USE_BALANCED_DELIMS: Require{}/[]matchingHARNESS_PARANOID: Enforce stricter schema sanity checks
- Standalone repro program
- Useful for ASan-based crash verification
Over the 10-day campaign:
- Generated thousands of unique inputs
- Observed crashes in schema validation when closing delimiters were not balanced
- Triage showed these were parse errors, not exploitable memory bugs
- Achieved deeper coverage by combining dictionary seeding with split-schema fuzzing
- Schema/object separation fuzzing increased code coverage compared to raw fuzzing
- Balanced delimiter filtering improved input quality and execution depth
- Automated triage was essential, reducing false positives significantly
- libucl’s parser is resilient, with most issues reducing to parse errors rather than memory safety bugs
- Extend harness with custom mutators for schema keywords
- Run with different sanitizers (MSan, TSan)