cybersecurity · beginner · ~10 min

Compose the libFuzzer entry point

Fuzz-harness contract: allocate, NUL-terminate, call, free.

Challenge

Write the body shared by every libFuzzer harness for a string parser: take the fuzzer's raw bytes, turn them into a NUL-terminated C string, hand them to the parser, and clean up.

Task

Implement int call_under_test_with_buffer(const unsigned char *data, int size, int (*parser)(const char *)) that:

  1. returns 0 immediately (skips) if data == NULL, parser == NULL, or size <= 0;
  2. allocates size + 1 bytes, copies size bytes from data, and NUL-terminates;
  3. calls parser on the copy;
  4. frees the copy;
  5. returns 0.

Input

  • data, size: the fuzzer's input bytes and length (the grader passes fixed inputs).
  • parser: the callback to invoke on the NUL-terminated copy.

Output

Always returns 0. The observable effect is that parser is called on a valid C string copy of data (and never called on degenerate input).

Example

data {'a','b','c'}, size 3   ->   parser receives "abc" (length 3), returns 0
data NULL, size 3            ->   parser not called, returns 0
data {'a','b','c'}, size 0   ->   parser not called, returns 0
parser NULL                  ->   nothing called, returns 0

Edge cases

  • size == 0, NULL data, or NULL parser: skip without calling parser.
  • Allocation must be size + 1 so the NUL terminator fits.

Rules

  • No leaks — free the copy on every non-skip path.

Why this matters

The libFuzzer entry-point signature is muscle memory. Write it once; reuse forever.

Input format

A byte buffer data with length size, and a parser callback.

Output format

Always 0; parser is called on a NUL-terminated copy unless input is degenerate.

Constraints

Skip on NULL/zero input; allocate size+1; always NUL-terminate and free.

Starter code

#include <stddef.h>
int call_under_test_with_buffer(const unsigned char *data, int size, int (*parser)(const char *)) { /* TODO */ (void)data; (void)size; (void)parser; return 0; }

Common mistakes

Forgetting +1 for NUL. Leaking on the early-return path.

Edge cases to handle

size == 0. NULL data. NULL parser.

Complexity

O(size).

Background lessons

Solve this exercise in the browser editor — compile and run against the test harness, no setup required.