executorch-mfv-poc-uses-backend-null-deref / poc /harness_program_fuzzer.cpp
tsk-arasu's picture
Upload folder using huggingface_hub
3bfbf53 verified
Raw
History Blame Contribute Delete
3.7 kB
// libFuzzer harness for executorch::runtime::Program::load()
// Targets the .pte flatbuffer parsing path (runtime/executor/program.cpp).
// Authorized local testing only - huntr MFV scope: ExecuTorch .pte parser.
#include <cstddef>
#include <cstdint>
#include <executorch/extension/data_loader/buffer_data_loader.h>
#include <executorch/runtime/executor/program.h>
#include <executorch/runtime/platform/runtime.h>
using executorch::extension::BufferDataLoader;
using executorch::runtime::Program;
static bool g_initialized = false;
extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t* data, std::size_t size) {
if (!g_initialized) {
executorch::runtime::runtime_init();
g_initialized = true;
}
constexpr std::size_t kMaxInput = 32U * 1024U * 1024U;
if (data == nullptr || size == 0 || size > kMaxInput) {
return 0;
}
BufferDataLoader loader(data, size);
// Try both verification levels - Minimal is the one used in perf-sensitive
// deployments and skips more validation than InternalConsistency.
auto program_ic = Program::load(&loader, Program::Verification::InternalConsistency);
if (getenv("ET_FUZZ_DEBUG")) {
fprintf(stderr, "[dbg] IC program.ok()=%d", program_ic.ok());
if (!program_ic.ok()) {
fprintf(stderr, " error=0x%x", static_cast<unsigned int>(program_ic.error()));
} else {
fprintf(stderr, " num_methods=%zu", program_ic.get().num_methods());
}
fprintf(stderr, "\n");
BufferDataLoader loader2(data, size);
auto program_min = Program::load(&loader2, Program::Verification::Minimal);
fprintf(stderr, "[dbg] Minimal program.ok()=%d", program_min.ok());
if (!program_min.ok()) {
fprintf(stderr, " error=0x%x", static_cast<unsigned int>(program_min.error()));
} else {
fprintf(stderr, " num_methods=%zu", program_min.get().num_methods());
}
fprintf(stderr, "\n");
}
if (program_ic.ok()) {
// Touch metadata to exercise more of the parsing surface.
auto& p = program_ic.get();
auto n = p.num_methods();
for (size_t i = 0; i < n; ++i) {
auto name = p.get_method_name(i);
if (name.ok()) {
auto meta = p.method_meta(name.get());
if (meta.ok()) {
auto& m = meta.get();
(void)m.name();
(void)m.num_inputs();
(void)m.num_outputs();
(void)m.num_attributes();
(void)m.num_memory_planned_buffers();
(void)m.num_instructions();
// uses_backend()/num_backends()/get_backend_name() exercise the
// ExecutionPlan::delegates() optional field - not guarded against
// null in uses_backend() per source review.
(void)m.uses_backend("XNNPACK");
(void)m.uses_backend("");
size_t nb = m.num_backends();
for (size_t bi = 0; bi < nb; ++bi) {
(void)m.get_backend_name(bi);
}
size_t na = m.num_attributes();
for (size_t ai = 0; ai < na && ai < 64; ++ai) {
(void)m.attribute_tensor_meta(ai);
}
size_t ni = m.num_inputs();
for (size_t ii = 0; ii < ni && ii < 64; ++ii) {
(void)m.input_tag(ii);
(void)m.input_tensor_meta(ii);
}
size_t no = m.num_outputs();
for (size_t oi = 0; oi < no && oi < 64; ++oi) {
(void)m.output_tag(oi);
(void)m.output_tensor_meta(oi);
}
size_t nmb = m.num_memory_planned_buffers();
for (size_t mi = 0; mi < nmb && mi < 64; ++mi) {
(void)m.memory_planned_buffer_size(mi);
(void)m.memory_planned_buffer_device(mi);
}
}
}
}
}
return 0;
}