Overview
LLVMFuzzerTestOneInput is the input interface function that a device or software under test provides to libFuzzer. In the cited coverage-guided fuzzing workflow, libFuzzer is linked with the device under test (DUT) for in-process fuzzing and calls this interface function repeatedly during the fuzzing process. The function receives generated input data, lets the DUT process it, and returns 0 to indicate that the input has been processed.
Role in libFuzzer
libFuzzer is described as an LLVM-based coverage-guided fuzzing engine that generates binary byte-stream inputs to maximize code coverage of the DUT. The DUT is instrumented by clang so that coverage information can be reported back to libFuzzer. libFuzzer then mutates inputs, such as by shuffling bytes or inserting bits, and periodically increases input size.
Because libFuzzer performs in-process fuzzing, it is linked with the DUT and communicates with it through specific interface functions. LLVMFuzzerTestOneInput is the input-facing callback in that interface: libFuzzer calls it many times, passing generated input to the DUT and receiving coverage feedback through the instrumented execution.
Typical structure
The evidence shows the interface in the form:
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
// allows one-time initialization on the first call
static bool initialized = do_initialization();
// ... process the input ...
// tell libFuzzer that the input has been processed
return 0;
}
The example highlights two common harness patterns:
- one-time initialization using a
staticvariable on the first invocation; and - returning
0after the current input has been processed.
Example use in instruction-set simulator fuzzing
In the referenced RISC-V instruction-set simulator verification workflow, the fuzzer generates a binary byte stream. That byte stream is interpreted as a sequence of instructions for the instruction-set simulator under test and embedded into an ELF testcase using a predefined ELF template. The generated testcase is then executed with tracing and compared against a reference simulator result, including register values and selected memory content.