From c62564d8e8f70a5df7d443a1c8abc998b2c06229 Mon Sep 17 00:00:00 2001 From: Alan Jowett Date: Tue, 14 May 2024 12:47:36 -0700 Subject: [PATCH] Skip local calls and fix ub behavior on le ops Signed-off-by: Alan Jowett --- libfuzzer/libfuzz_harness.cc | 17 +++++++++++++++++ ubpf/disassembler.py | 4 ++++ vm/ubpf_vm.c | 1 + 3 files changed, 22 insertions(+) diff --git a/libfuzzer/libfuzz_harness.cc b/libfuzzer/libfuzz_harness.cc index c8b5d79e..4756caf8 100644 --- a/libfuzzer/libfuzz_harness.cc +++ b/libfuzzer/libfuzz_harness.cc @@ -89,6 +89,23 @@ int LLVMFuzzerTestOneInput(const uint8_t* data, std::size_t size) return -1; } + if ((program_length % sizeof(ebpf_inst)) != 0) { + // The program length needs to be a multiple of sizeof(ebpf_inst_t). + // This is not interesting, as the fuzzer input is invalid. + // Do not add it to the corpus. + return -1; + } + + for (std::size_t i = 0; i < program_length / sizeof(ebpf_inst); i++) { + ebpf_inst inst = reinterpret_cast(program_start)[i]; + if (inst.opcode == EBPF_OP_CALL && inst.src == 1) { + // Until local calls are fixed, reject local calls. + // This is not interesting, as the fuzzer input is invalid. + // Do not add it to the corpus. + return -1; + } + } + // Copy any input memory into a writable buffer. if (memory_length > 0) { memory.resize(memory_length); diff --git a/ubpf/disassembler.py b/ubpf/disassembler.py index b39f7cf5..bd78b255 100644 --- a/ubpf/disassembler.py +++ b/ubpf/disassembler.py @@ -128,6 +128,8 @@ def disassemble_one(data, offset): if opcode_name == "exit": return opcode_name elif opcode_name == "call": + if src_reg == 1: + opcode_name += " local" return "%s %s" % (opcode_name, I(imm)) elif opcode_name == "ja": return "%s %s" % (opcode_name, O(off)) @@ -143,6 +145,8 @@ def disassemble_one(data, offset): if opcode_name == "exit": return opcode_name elif opcode_name == "call": + if src_reg == 1: + opcode_name += " local" return "%s %s" % (opcode_name, I(imm)) elif opcode_name == "ja": return "%s %s" % (opcode_name, O(off)) diff --git a/vm/ubpf_vm.c b/vm/ubpf_vm.c index 58f9d7e3..076ec169 100644 --- a/vm/ubpf_vm.c +++ b/vm/ubpf_vm.c @@ -491,6 +491,7 @@ ubpf_validate_shadow_register(const struct ubpf_vm* vm, uint16_t* shadow_registe case 0x90: // EBPF_OP_MOD case 0xa0: // EBPF_OP_XOR case 0xc0: // EBPF_OP_ARSH + case 0xd0: // EBPF_OP_LE dst_register_required = true; break; case 0xb0: // EBPF_OP_MOV