cybersecurity · intermediate · ~15 min · safe pentest lab
A real fuzz-target signature with the bounds-safety discipline a fuzzer will exercise.
Write a libFuzzer-shape target that walks a length-prefixed record stream and survives any input a fuzzer can throw at it.
Implement the standard fuzz-target signature:
#include <stdint.h>
#include <stddef.h>
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
Parse data as a stream of records, each laid out as:
[len:u8][type:u8][payload: len-1 bytes]
Count the records whose type == 0x01 and return that count.
data, size: the fuzzer-supplied bytes and their length. The grader passes hand-crafted edge inputs.Returns a non-negative int: the number of type == 0x01 records seen before the walk stops. The function must never crash.
{0x01,0x02, 0x01,0x01} -> 1 (two len=1 records, one is type 1)
{0x01,0x01, 0x02,0x01,0xAA, 0x01,0x01} -> 3
{0x01,0x01, 0x10,0x01} -> 1 (second len=16 walks past end: stop)
{0x01,0x01, 0x00,0xFF, 0x01,0x01} -> 1 (len==0 stops the walk)
NULL/size 0 -> 0
size == 0 or data == NULL: return 0.len == 0: stop the walk, return the count so far.len would read past size: stop the walk (never read past data[size - 1]).len is one byte; the next record starts at off + len + 1.The fuzz-target signature is a portable contract. Match it once and every popular fuzzer can drive your parser.
A byte buffer data and its length size.
A non-negative int: the count of type-0x01 records before the walk stops.
No crashes on any input; no allocation; never read past data[size - 1].
#include <stdint.h>
#include <stddef.h>
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
/* TODO */
(void)data; (void)size;
return 0;
}
Returning -1 when input is bad (the fuzz target should always succeed). Reading data[off+1] before bounds-checking. Allowing len==0 to loop forever.
size 0. data NULL with size 0. Single byte. All-junk input.
O(size).
Solve this exercise in the browser editor — compile and run against the test harness, no setup required.