From 198824230f2c16fa8997b6f4fa0129ea6744878d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Mei=C3=9Fner?= Date: Mon, 20 May 2024 20:07:31 +0200 Subject: [PATCH] Fix - Verify imm not offset in CALL_IMM (#568) * Adds check_call_target() to verifier. * Fixes fuzz_targets. --- fuzz/fuzz_targets/smart_jit_diff.rs | 2 +- fuzz/fuzz_targets/smarter_jit_diff.rs | 6 +++--- src/verifier.rs | 12 +++++++++++- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/fuzz/fuzz_targets/smart_jit_diff.rs b/fuzz/fuzz_targets/smart_jit_diff.rs index 4e05ecb3..d085a0d0 100644 --- a/fuzz/fuzz_targets/smart_jit_diff.rs +++ b/fuzz/fuzz_targets/smart_jit_diff.rs @@ -78,7 +78,7 @@ fuzz_target!(|data: FuzzData| { #[allow(unused)] let (_interp_ins_count, interp_res) = interp_vm.execute_program(&executable, true); - #[cfg(all(feature = "jit", not(target_os = "windows"), target_arch = "x86_64"))] + #[cfg(all(not(target_os = "windows"), target_arch = "x86_64"))] if executable.jit_compile().is_ok() { let mut jit_mem = data.mem; let mut jit_context_object = TestContextObject::new(1 << 16); diff --git a/fuzz/fuzz_targets/smarter_jit_diff.rs b/fuzz/fuzz_targets/smarter_jit_diff.rs index 5a5fd4ee..476ba689 100644 --- a/fuzz/fuzz_targets/smarter_jit_diff.rs +++ b/fuzz/fuzz_targets/smarter_jit_diff.rs @@ -68,7 +68,7 @@ fuzz_target!(|data: FuzzData| { #[allow(unused)] let (_interp_ins_count, interp_res) = interp_vm.execute_program(&executable, true); - #[cfg(all(feature = "jit", not(target_os = "windows"), target_arch = "x86_64"))] + #[cfg(all(not(target_os = "windows"), target_arch = "x86_64"))] if executable.jit_compile().is_ok() { let mut jit_mem = data.mem; let mut jit_context_object = TestContextObject::new(1 << 16); @@ -85,8 +85,8 @@ fuzz_target!(|data: FuzzData| { let (_jit_ins_count, jit_res) = jit_vm.execute_program(&executable, false); if format!("{:?}", interp_res) != format!("{:?}", jit_res) { // spot check: there's a meaningless bug where ExceededMaxInstructions is different due to jump calculations - if interp_res_str.contains("ExceededMaxInstructions") - && jit_res_str.contains("ExceededMaxInstructions") + if format!("{:?}", interp_res).contains("ExceededMaxInstructions") + && format!("{:?}", jit_res).contains("ExceededMaxInstructions") { return; } diff --git a/src/verifier.rs b/src/verifier.rs index 63cf1129..0f1d5e52 100644 --- a/src/verifier.rs +++ b/src/verifier.rs @@ -164,6 +164,16 @@ fn check_jmp_offset( Ok(()) } +fn check_call_target( + key: u32, + function_registry: &FunctionRegistry, +) -> Result<(), VerifierError> { + function_registry + .lookup_by_key(key) + .map(|_| ()) + .ok_or(VerifierError::InvalidFunction(key as usize)) +} + fn check_registers( insn: &ebpf::Insn, store: bool, @@ -371,7 +381,7 @@ impl Verifier for RequisiteVerifier { ebpf::JSLT_REG => { check_jmp_offset(prog, insn_ptr, &function_range)?; }, ebpf::JSLE_IMM => { check_jmp_offset(prog, insn_ptr, &function_range)?; }, ebpf::JSLE_REG => { check_jmp_offset(prog, insn_ptr, &function_range)?; }, - ebpf::CALL_IMM if sbpf_version.static_syscalls() && insn.src != 0 => { check_jmp_offset(prog, insn_ptr, &program_range)?; }, + ebpf::CALL_IMM if sbpf_version.static_syscalls() && insn.src != 0 => { check_call_target(insn.imm as u32, function_registry)?; }, ebpf::CALL_IMM => {}, ebpf::CALL_REG => { check_callx_register(&insn, insn_ptr, config, sbpf_version)?; }, ebpf::EXIT => {},