libfuzzer
Sets up and runs libFuzzer, the coverage-guided fuzzer built into LLVM, on C/C++ code that compiles with Clang. Covers harness structure, -fsanitize=fuzzer builds, corpus and dictionary management, sanitizer integration, and campaign triage
Install / Use
npx skills add trailofbits/skills --skill libfuzzerInstalls into whichever agent you are using.
SKILL.md
Installable skill definition
Quality Score
Category
Content & MediaSupported Platforms
Tags
Our assessment of libfuzzer
libfuzzer scores 96/100 on our quality scale, 54th of 710 Content & Media skills we index (top 8%).
Its SKILL.md is 24 KB long, well organised into 70 sections with 58 code examples: a thorough specification that gives an agent plenty to work with.
With 7,225 GitHub stars, it is one of the more widely adopted skills in the catalogue.
Maintenance, license and trust
- The repository was last updated 4 days ago, so libfuzzer is actively maintained.
- It is released under the CC-BY-SA-4.0 license; check its terms before commercial use.
- Its trust signals score 100/100, with no cautions. These come from repository metadata, not a code audit — read the skill file before letting an agent act on it.
Safety scan
No issues foundOur scan of the whole file found no instruction hijacking, hidden characters, credential access, data exfiltration or destructive commands.
Automated pattern scan on 2026-09-28. It catches known dangerous patterns, not every risk — read a skill before letting an agent act on it.
libfuzzer compared with similar skills
All 4 of these similar skills score higher than libfuzzer; compare them before choosing.
| Skill | Score | Stars | Updated | Format |
|---|---|---|---|---|
| libfuzzer (this skill)by trailofbits | 96 | 7.2k | 4d ago | SKILL.md |
| siyuanby siyuan-note | 100 | 46.5k | today | MCP Server |
| algorithmic-artby anthropics | 100 | 177.9k | 5d ago | SKILL.md |
| pptxby anthropics | 100 | 177.9k | 5d ago | SKILL.md |
| designby nextlevelbuilder | 100 | 130.2k | 6d ago | SKILL.md |
Frequently asked questions
- How do I install libfuzzer?
- Run
npx skills add trailofbits/skills --skill libfuzzer. The install tabs above show the steps for each supported agent. - Which AI agents does libfuzzer work with?
- It is written for Universal, as a SKILL.md file. Other agents that read the same format can often use it too.
- Is libfuzzer safe to use?
- Our scan of the whole file found no instruction hijacking, hidden characters, credential access, data exfiltration or destructive commands. It is CC-BY-SA-4.0-licensed and scores 100/100 on trust signals. Skills are instructions an agent will follow, so read the file before installing it and do not approve commands you do not understand.
- Is libfuzzer still maintained?
- The repository was last updated 4 days ago, so libfuzzer is actively maintained.
Skill content
View source on GitHubname: libfuzzer type: fuzzer description: "Sets up and runs libFuzzer, the coverage-guided fuzzer built into LLVM, on C/C++ code that compiles with Clang. Covers harness structure, -fsanitize=fuzzer builds, corpus and dictionary management, sanitizer integration, and campaign triage. Use when writing or debugging an LLVMFuzzerTestOneInput harness, starting fuzzing on a C/C++ library, choosing between libFuzzer and AFL++, or working out why a libFuzzer run finds nothing."
libFuzzer
libFuzzer is an in-process, coverage-guided fuzzer that is part of the LLVM project. It's the recommended starting point for fuzzing C/C++ projects due to its simplicity and integration with the LLVM toolchain. While libFuzzer has been in maintenance-only mode since late 2022, it is easier to install and use than its alternatives, has wide support, and will be maintained for the foreseeable future.
When to Use
| Fuzzer | Best For | Complexity | |--------|----------|------------| | libFuzzer | Quick setup, single-project fuzzing | Low | | AFL++ | Multi-core fuzzing, diverse mutations | Medium | | LibAFL | Custom fuzzers, research projects | High | | Honggfuzz | Hardware-based coverage | Medium |
Choose libFuzzer when:
- You need a simple, quick setup for C/C++ code
- Project uses Clang for compilation
- Single-core fuzzing is sufficient initially
- Transitioning to AFL++ later is an option (harnesses are compatible)
Note: Fuzzing harnesses written for libFuzzer are compatible with AFL++, making it easy to transition if you need more advanced features like better multi-core support.
Quick Start
#include <stdint.h>
#include <stddef.h>
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
// Validate input if needed
if (size < 1) return 0;
// Call your target function with fuzzer-provided data
my_target_function(data, size);
return 0;
}
Compile and run:
clang++ -fsanitize=fuzzer,address -g -O2 harness.cc target.cc -o fuzz
mkdir corpus/
./fuzz corpus/
Installation
Prerequisites
- LLVM/Clang compiler (includes libFuzzer)
- LLVM tools for coverage analysis (optional)
Linux (Ubuntu/Debian)
apt install clang llvm
For the latest LLVM version:
# Add LLVM repository from apt.llvm.org
# Then install specific version, e.g.:
apt install clang-18 llvm-18
macOS
# Using Homebrew
brew install llvm
# Or using Nix
nix-env -i clang
Windows
Install Clang through Visual Studio. Refer to Microsoft's documentation for setup instructions.
Recommendation: If possible, fuzz on a local x86_64 VM or rent one on DigitalOcean, AWS, or Hetzner. Linux provides the best support for libFuzzer.
Verification
clang++ --version
# Should show LLVM version information
Writing a Harness
Harness Structure
The harness is the entry point for the fuzzer. libFuzzer calls the LLVMFuzzerTestOneInput function repeatedly with different inputs.
#include <stdint.h>
#include <stddef.h>
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
// 1. Optional: Validate input size
if (size < MIN_REQUIRED_SIZE) {
return 0; // Reject inputs that are too small
}
// 2. Optional: Convert raw bytes to structured data
// Example: Parse two integers from byte array
if (size >= 2 * sizeof(uint32_t)) {
uint32_t a = *(uint32_t*)(data);
uint32_t b = *(uint32_t*)(data + sizeof(uint32_t));
my_function(a, b);
}
// 3. Call target function
target_function(data, size);
// 4. Always return 0 (non-zero reserved for future use)
return 0;
}
Harness Rules
| Do | Don't |
|----|-------|
| Handle all input types (empty, huge, malformed) | Call exit() - stops fuzzing process |
| Join all threads before returning | Leave threads running |
| Keep harness fast and simple | Add excessive logging or complexity |
| Maintain determinism | Use random number generators or read /dev/random |
| Reset global state between runs | Rely on state from previous executions |
| Use narrow, focused targets | Mix unrelated data formats (PNG + TCP) in one harness |
Rationale:
- Speed matters: Aim for 100s-1000s executions per second per core
- Reproducibility: Crashes must be reproducible after fuzzing completes
- Isolation: Each execution should be independent
Using FuzzedDataProvider for Complex Inputs
For complex inputs (strings, multiple parameters), use the FuzzedDataProvider helper:
#include <stdint.h>
#include <stddef.h>
#include "FuzzedDataProvider.h" // From LLVM project
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
FuzzedDataProvider fuzzed_data(data, size);
// Extract structured data
size_t allocation_size = fuzzed_data.ConsumeIntegral<size_t>();
std::vector<char> str1 = fuzzed_data.ConsumeBytesWithTerminator<char>(32, 0xFF);
std::vector<char> str2 = fuzzed_data.ConsumeBytesWithTerminator<char>(32, 0xFF);
// Call target with extracted data
char* result = concat(&str1[0], str1.size(), &str2[0], str2.size(), allocation_size);
if (result != NULL) {
free(result);
}
return 0;
}
Download FuzzedDataProvider.h from the LLVM repository.
Interleaved Fuzzing
Use a single harness to test multiple related functions:
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
if (size < 1 + 2 * sizeof(int32_t)) {
return 0;
}
uint8_t mode = data[0];
int32_t numbers[2];
memcpy(numbers, data + 1, 2 * sizeof(int32_t));
// Select function based on first byte
switch (mode % 4) {
case 0: add(numbers[0], numbers[1]); break;
case 1: subtract(numbers[0], numbers[1]); break;
case 2: multiply(numbers[0], numbers[1]); break;
case 3: divide(numbers[0], numbers[1]); break;
}
return 0;
}
See Also: For detailed harness writing techniques, patterns for handling complex inputs, structure-aware fuzzing, and protobuf-based fuzzing, see the fuzz-harness-writing technique skill.
Compilation
Basic Compilation
The key flag is -fsanitize=fuzzer, which:
- Links the libFuzzer runtime (provides
mainfunction) - Enables SanitizerCoverage instrumentation for coverage tracking
- Disables built-in functions like
memcmp
clang++ -fsanitize=fuzzer -g -O2 harness.cc target.cc -o fuzz
Flags explained:
-fsanitize=fuzzer: Enable libFuzzer-g: Add debug symbols (helpful for crash analysis)-O2: Production-level optimizations (recommended for fuzzing)-DNO_MAIN: Define macro if your code has amainfunction
With Sanitizers
AddressSanitizer (recommended):
clang++ -fsanitize=fuzzer,address -g -O2 -U_FORTIFY_SOURCE harness.cc target.cc -o fuzz
Multiple sanitizers:
clang++ -fsanitize=fuzzer,address,undefined -g -O2 harness.cc target.cc -o fuzz
See Also: For detailed sanitizer configuration, common issues, ASAN_OPTIONS flags, and advanced sanitizer usage, see the address-sanitizer and undefined-behavior-sanitizer technique skills.
Build Flags
| Flag | Purpose |
|------|---------|
| -fsanitize=fuzzer | Enable libFuzzer runtime and instrumentation |
| -fsanitize=address | Enable AddressSanitizer (memory error detection) |
| -fsanitize=undefined | Enable UndefinedBehaviorSanitizer |
| -fsanitize=fuzzer-no-link | Instrument without linking fuzzer (for libraries) |
| -g | Include debug symbols |
| -O2 | Production optimization level |
| -U_FORTIFY_SOURCE | Disable fortification (can interfere with ASan) |
Building Static Libraries
For projects that produce static libraries:
- Build the library with fuzzing instrumentation:
export CC=clang CFLAGS="-fsanitize=fuzzer-no-link -fsanitize=address"
export CXX=clang++ CXXFLAGS="$CFLAGS"
./configure --enable-shared=no
make
- Link the static library with your harness:
clang++ -fsanitize=fuzzer -fsanitize=address harness.cc libmylib.a -o fuzz
CMake Integration
project(FuzzTarget)
cmake_minimum_required(VERSION 3.0)
add_executable(fuzz main.cc harness.cc)
target_compile_definitions(fuzz PRIVATE NO_MAIN=1)
target_compile_options(fuzz PRIVATE -g -O2 -fsanitize=fuzzer -fsanitize=address)
target_link_libraries(fuzz -fsanitize=fuzzer -fsanitize=address)
Build with:
cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ .
cmake --build .
Corpus Management
Creating Initial Corpus
Create a directory for the corpus (can start empty):
mkdir corpus/
Optional but recommended: Provide seed inputs (valid example files):
# For a PNG parser:
cp examples/*.png corpus/
# For a protocol parser:
cp test_packets/*.bin corpus/
Benefits of seed inputs:
- Fuzzer doesn't start from scratch
- Reaches valid code paths faster
- Significantly improves effectiveness
Corpus Structure
The corpus directory contains:
- Input files that trigger unique code paths
- Minimized versions (libFuzzer automatically minimizes)
- Named by content hash (e.g.,
a9993e364706816aba3e25717850c26c9cd0d89d)
Corpus Minimization
libFuzzer automatically minimizes corpus entries during fuzzing. To explicitly minimize:
mkdir minimized_corpus/
./fuzz -merge=1 minimized_corpus/ corpus/
This creates a deduplicated, minimized corpus in minimized_corpus/.
See Also: For corpus creation strategies, seed selection, format-specific corpus building, and corpus maintenance, see the fuzzing-corpus technique skill.
Running Campaigns
Basic Run
./fuzz corpus/
This runs until a crash is found or you stop it (Ctrl+C).
Recommended: Continue After Crashes
./fuzz -fork=1 -ignore_crashes=1 corpus/
The -fork and -ignore_crashes flags (experimental but widely used) allow fuzzing to continue after finding crashes.
Common Options
Control input size:
./fuzz -max_len=4000 corpus/
Rule of thumb: 2x the size of minimal realistic input.
Set timeout:
./fuzz -timeout=2 corpus/
Abort test cases that run longer than 2 seconds.
Use a dictionary:
./fuzz -dict=./format.dict corpus/
Close stdout/stderr (speed up fuzzing):
./fuzz -close_fd_mask=3 corpus/
See all options:
./fuzz -help=1
Multi-Core Fuzzing
Option 1: Jobs and workers (recommended):
./fuzz -jobs=4 -workers=4 -fork=1 -ignore_crashes=1 corpus/
-jobs=4: Run 4 sequential campaigns-workers=4: Process jobs in parallel with 4 processes- Test cases are shared between jobs
Option 2: Fork mode:
./fuzz -fork=4 -ignore_crashes=1 corpus/
Note: For serious multi-core fuzzing, consider switching to AFL++, Honggfuzz, or LibAFL.
Re-executing Test Cases
Re-run a single crash:
./fuzz ./crash-a9993e364706816aba3e25717850c26c9cd0d89d
Test all inputs in a directory without fuzzing:
./fuzz -runs=0 corpus/
Interpreting Output
When fuzzing runs, you'll see statistics like:
INFO: Seed: 3517090860
INFO: Loaded 1 modules (9 inline 8-bit counters)
#2 INITED cov: 3 ft: 4 corp: 1/1b exec/s: 0 rss: 26Mb
#57 NEW cov: 4 ft: 5 corp: 2/4b lim: 4 exec/s: 0 rss: 26Mb
| Output | Meaning |
|--------|---------|
| INITED | Fuzzing initialized |
| NEW | New coverage found, added to corpus |
| REDUCE | Input minimized while keeping coverage |
| cov: N | Number of coverage edges hit |
| corp: X/Yb | Corpus size: X entries, Y total bytes |
| exec/s: N | Executions per second |
| rss: NMb | Resident memory usag
Truncated for display — read the full file on GitHub.
Related Skills
siyuan
46.5kAn open-source, privacy-first, self-hosted knowledge workspace where humans and AI agents work together 开源、隐私优先、自托管的知识工作空间,让人与智能体在此协作
algorithmic-art
177.9kCreating algorithmic art using p5.js with seeded randomness and interactive parameter exploration. Use this when users request creating art using code, generative art, algorithmic art, flow fields, or particle systems.
pptx
177.9kUse this skill any time a .pptx or .potx file is involved in any way — as input, output, or both. This includes: creating slide decks, pitch decks, or presentations; reading, parsing, or extracting text from any .pptx or .potx file (even if the extracted content will be used elsewhere, like in an em…
design
130.2kComprehensive design skill: brand identity, design tokens, UI styling, logo generation (55 styles, Gemini, Atlas Cloud, or MuAPI AI), corporate identity program (50 deliverables, CIP mockups), HTML presentations (Chart.js), banner design (22 styles, social/ads/web/print), icon design (15 styles, SVG…
Languages
Trust signals
From repository metadata: license, adoption, age and documentation. Not a code audit — see the Safety scan above for what the skill file itself contains.
