crucible-mutator¶
CGo library that exposes Crucible's structure-aware mutator as a libFuzzer custom mutator and crossover implementation.
Purpose¶
When linked into a libFuzzer harness, crucible-mutator replaces libFuzzer's default byte-level mutation with Crucible's structure-aware mutation engine. This means every mutation operates on parsed structures rather than random bytes, dramatically improving code coverage in deep parsing paths.
The -mutator harness variants (e.g., crucible-libfuzzer-deep-mutator) use this library.
Build¶
# Build the C archive from the project root
CGO_ENABLED=1 go build -buildmode=c-archive -o harness/libfuzzer/libcruciblemut.a ./cmd/crucible-mutator
# Or via the harness Makefile
make -C harness/libfuzzer go-mutator
This produces libcruciblemut.a and libcruciblemut.h, which are linked into harness binaries at compile time.
Exported Functions¶
LLVMFuzzerCustomMutator¶
Called by libFuzzer instead of its built-in mutator. Performs structure-aware mutation:
- Copies the input buffer into Go-managed memory
- Parses the bytes as a GGUF file
- Applies 1–3 weighted random mutations via
mutator.MutateBytes() - Writes the result back into libFuzzer's buffer (truncated to
maxSize) - Returns the output length
If mutation fails (e.g., input is not parseable as GGUF), returns the original input unchanged.
LLVMFuzzerCustomCrossOver¶
size_t LLVMFuzzerCustomCrossOver(
const uint8_t *data1, size_t size1,
const uint8_t *data2, size_t size2,
uint8_t *out, size_t maxOutSize,
unsigned int seed);
Called by libFuzzer to combine two corpus entries. Implements structure-aware crossover:
- Parses both inputs as GGUF files
- Applies one of 5 crossover strategies (header swap, metadata merge, tensor info swap, data splice, full recombination)
- Serializes the result into the output buffer
Falls back to mutation of the first input if crossover fails, or returns the first input verbatim if both fail.
Usage¶
The mutator library is not used directly. Instead, build a -mutator variant of any harness:
# Build the deep harness with custom mutator
make -C harness/libfuzzer deep-mutator LLAMA_CPP=~/src/llama.cpp
# Run it — libFuzzer automatically detects and uses the custom mutator
./harness/libfuzzer/crucible-libfuzzer-deep-mutator corpus/ \
-artifact_prefix=crashes/ \
-max_len=10485760 \
-timeout=30
Available -mutator variants: mutator, deep-mutator, model-mutator, clip-mutator, quant-mutator, roundtrip-mutator, dequant-mutator.