31. Fuzzing a real parsing bug with libFuzzer
Fuzzing feeds a function millions of randomly-mutated inputs, guided by code-coverage feedback, looking for inputs that crash it or trip a sanitizer. It is the technique that found the bug class behind Heartbleed-style CVEs across the industry after the fact (Google's OSS-Fuzz alone has found 10,000+ bugs in open-source C/C++ projects).
// fuzz_target.c — libFuzzer calls this function with random byte arrays
#include <stdint.h>
#include <stddef.h>
#include <string.h>
int parse_length_prefixed(const unsigned char *data, size_t data_len,
unsigned char *out, size_t out_cap); // from Section 29.3
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
unsigned char out[256];
parse_length_prefixed(data, size, out, sizeof out);
return 0;
}
clang -std=c17 -g -fsanitize=fuzzer,address -o fuzz_target fuzz_target.c parser.c
./fuzz_target # runs indefinitely, mutating inputs, until it finds a crash
./fuzz_target crash-abc123 # re-run just the one input that crashed, to reproduce/debug
Feed it the version of parse_length_prefixed without the bounds
checks from Section 29.3 and libFuzzer will find the overflow in seconds,
saving the exact crashing input to disk — this before/after comparison
is the single most convincing five-minute demo of why input validation
matters in C.