From 8747f87fe4041c821ad8547dcb2467c91201762d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Mei=C3=9Fner?= Date: Thu, 12 Sep 2024 16:04:50 +0200 Subject: [PATCH] Fix - JIT instruction meter in `ExecutionOverrun` (#591) * Fixes missing pc reporting in JIT when throwing EbpfError::ExecutionOverrun. * Adds missing test coverage for EbpfError::ExecutionOverrun. --- src/jit.rs | 5 +++-- tests/execution.rs | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/src/jit.rs b/src/jit.rs index c5de89b8..395c3882 100644 --- a/src/jit.rs +++ b/src/jit.rs @@ -731,8 +731,9 @@ impl<'a, C: ContextObject> JitCompiler<'a, C> { // Bumper in case there was no final exit if self.offset_in_text_section + MAX_MACHINE_CODE_LENGTH_PER_INSTRUCTION * 2 >= self.result.text_section.len() { return Err(EbpfError::ExhaustedTextSegment(self.pc)); - } - self.emit_validate_and_profile_instruction_count(true, false, Some(self.pc + 2)); + } + self.emit_validate_and_profile_instruction_count(true, false, Some(self.pc + 1)); + self.emit_ins(X86Instruction::load_immediate(OperandSize::S64, REGISTER_SCRATCH, self.pc as i64)); // Save pc self.emit_set_exception_kind(EbpfError::ExecutionOverrun); self.emit_ins(X86Instruction::jump_immediate(self.relative_to_anchor(ANCHOR_THROW_EXCEPTION, 5))); diff --git a/tests/execution.rs b/tests/execution.rs index e7f77ce2..424005b1 100644 --- a/tests/execution.rs +++ b/tests/execution.rs @@ -3475,12 +3475,47 @@ fn test_err_fixed_stack_out_of_bound() { ); } +#[test] +fn test_execution_overrun() { + let config = Config { + enabled_sbpf_versions: SBPFVersion::V1..=SBPFVersion::V1, + ..Config::default() + }; + test_interpreter_and_jit_asm!( + " + add r1, 0", + config.clone(), + [], + (), + TestContextObject::new(2), + ProgramResult::Err(EbpfError::ExecutionOverrun), + ); + test_interpreter_and_jit_asm!( + " + add r1, 0", + config.clone(), + [], + (), + TestContextObject::new(1), + ProgramResult::Err(EbpfError::ExceededMaxInstructions), + ); +} + #[test] fn test_lddw() { let config = Config { enabled_sbpf_versions: SBPFVersion::V1..=SBPFVersion::V1, ..Config::default() }; + test_interpreter_and_jit_asm!( + " + lddw r0, 0x1122334455667788", + config.clone(), + [], + (), + TestContextObject::new(2), + ProgramResult::Err(EbpfError::ExecutionOverrun), + ); test_interpreter_and_jit_asm!( " lddw r0, 0x1122334455667788