Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve verifier fuzzer #3431

Merged
merged 8 commits into from
Apr 19, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 27 additions & 2 deletions tests/libfuzzer/verifier_fuzzer/libfuzz_harness.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#include "bpf/bpf.h"
#include "bpf/libbpf.h"
#include "ebpf_api.h"
#undef max
#include "elfio/elfio.hpp"
#include "libfuzzer.h"
#include "test_helper.hpp"

Expand All @@ -16,6 +18,8 @@ extern "C" size_t cxplat_fuzzing_memory_limit;

FUZZ_EXPORT int __cdecl LLVMFuzzerInitialize(int*, char***) { return 0; }

// Treat the input data as an ELF file and a block of data to be passed to the program.
// Load the ELF file and run each program in the ELF file with the data as input.
FUZZ_EXPORT int __cdecl LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{
cxplat_fuzzing_memory_limit = 1024 * 1024;
Expand All @@ -41,11 +45,29 @@ FUZZ_EXPORT int __cdecl LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
bpf_object__for_each_program(program, bpf_object)
{
bpf_test_run_opts test_attr = {};
// For now, limit the size of the data to 4096 bytes.
// The IOCTL interface limits the total message size to 64k, so this should leave extra space.
uint8_t program_data[4096] = {0};
uint32_t program_data_size = 0;
uint8_t context[4096] = {0};

std::stringstream stream(std::string((const char*)data, size));

ELFIO::elfio reader;
// Read the ELF file from the stream to determine its length.
// This leaves the stream at the end of the ELF file.
// All data after the ELF file is considered the data to be passed to the program.
if (!reader.load(stream)) {
return 0;
Alan-Jowett marked this conversation as resolved.
Show resolved Hide resolved
}

// Copy the remaining data into the program_data buffer.
stream.read((char*)program_data, sizeof(program_data));

program_data_size = static_cast<uint32_t>(stream.gcount());

test_attr.data_in = program_data;
test_attr.data_size_in = sizeof(program_data);
test_attr.data_size_in = program_data_size;
test_attr.data_out = program_data;
test_attr.data_size_out = sizeof(program_data);
test_attr.repeat = 1;
Expand All @@ -59,7 +81,10 @@ FUZZ_EXPORT int __cdecl LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
if (bpf_prog_test_run_opts(bpf_program__fd(program), &test_attr) != 0) {
break;
}
printf("Program %s ran successfully\n", bpf_program__name(program));
printf(
"Program %s ran successfully with %d bytes of data\n",
bpf_program__name(program),
program_data_size);
}
}

Expand Down
Loading