Secure Coding in C · intermediate · ~15 min

Shape of a libFuzzer-compatible defensive target

Write a function with libFuzzer's `LLVMFuzzerTestOneInput` signature that parses a record stream without crashing.

Overview

Same TLV-walk discipline as parse-bt-advertisement, lifted into libFuzzer's standard entry-point signature.

Why it matters

The fuzz-target shape is a portable contract. Once your code matches it, every popular fuzzer can drive it.

Lesson

Why this matters

A fuzz target is a single function. libFuzzer, AFL++, Honggfuzz — all the popular fuzzers drive their target via:

int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);

The contract:

  • The function must accept any data / size without crashing.
  • It must return 0 (libFuzzer ignores the return value otherwise).
  • It must not write to globals.
  • It must not allocate without freeing.

We're not running a real fuzzer in the harness. We're writing the shape of a defensive target and proving it survives edge inputs.

The toy record format we'll parse

[ len : u8 ][ type : u8 ][ payload : len - 1 bytes ]

The fuzz target counts records whose type == 0x01. Edge cases that must NOT crash:

  • size == 0 → return 0
  • data == NULL (with size 0) → return 0
  • A record's len walks past size → stop counting, return what we have so far (no read past end).
  • len == 0 → stop (would loop forever).

Your job

Implement int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) that walks the record stream, never reads past size, returns the count of type-0x01 records.

Common mistakes

  • Forgetting to bounds-check len before advancing.
  • Allowing len == 0 to spin.
  • Allocating memory in the target (a fuzz target should be allocation-free per call where possible).

What this is NOT

  • A live fuzzer driver. The harness calls the function with hand- crafted inputs to prove it survives them all.
  • An exploit generator. A fuzz target finds crashes; it does not weaponise them.

Summary

LLVMFuzzerTestOneInput, bounds-checked TLV walk, no allocation, never crash.

Practice with these exercises