From d56e0e1e8e89a50d2a3fe53a29cde3aa91a93fcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Mei=C3=9Fner?= Date: Thu, 3 Aug 2023 19:18:25 +0200 Subject: [PATCH] Disables little-endian byte swap instructions in SBPFv2. (#493) --- src/elf.rs | 5 +++++ src/interpreter.rs | 2 +- src/jit.rs | 2 +- src/verifier.rs | 2 +- tests/execution.rs | 25 +++++++++++++++++-------- 5 files changed, 25 insertions(+), 11 deletions(-) diff --git a/src/elf.rs b/src/elf.rs index 8b17d1143..ce1218b0c 100644 --- a/src/elf.rs +++ b/src/elf.rs @@ -220,6 +220,11 @@ pub enum SBPFVersion { } impl SBPFVersion { + /// Enable the little-endian byte swap instructions + pub fn enable_le(&self) -> bool { + self == &SBPFVersion::V1 + } + /// Enable the negation instruction pub fn enable_neg(&self) -> bool { self == &SBPFVersion::V1 diff --git a/src/interpreter.rs b/src/interpreter.rs index 218ab1b4b..7dd294eec 100644 --- a/src/interpreter.rs +++ b/src/interpreter.rs @@ -316,7 +316,7 @@ impl<'a, 'b, V: Verifier, C: ContextObject> Interpreter<'a, 'b, V, C> { ebpf::MOV32_REG => self.reg[dst] = (self.reg[src] as u32) as u64, ebpf::ARSH32_IMM => self.reg[dst] = (self.reg[dst] as i32).wrapping_shr(insn.imm as u32) as u64 & (u32::MAX as u64), ebpf::ARSH32_REG => self.reg[dst] = (self.reg[dst] as i32).wrapping_shr(self.reg[src] as u32) as u64 & (u32::MAX as u64), - ebpf::LE => { + ebpf::LE if self.executable.get_sbpf_version().enable_le() => { self.reg[dst] = match insn.imm { 16 => (self.reg[dst] as u16).to_le() as u64, 32 => (self.reg[dst] as u32).to_le() as u64, diff --git a/src/jit.rs b/src/jit.rs index a3d67142c..aeced76bf 100644 --- a/src/jit.rs +++ b/src/jit.rs @@ -523,7 +523,7 @@ impl<'a, V: Verifier, C: ContextObject> JitCompiler<'a, V, C> { ebpf::MOV32_REG => self.emit_ins(X86Instruction::mov(OperandSize::S32, src, dst)), ebpf::ARSH32_IMM => self.emit_shift(OperandSize::S32, 7, R11, dst, Some(insn.imm)), ebpf::ARSH32_REG => self.emit_shift(OperandSize::S32, 7, src, dst, None), - ebpf::LE => { + ebpf::LE if self.executable.get_sbpf_version().enable_le() => { match insn.imm { 16 => { self.emit_ins(X86Instruction::alu(OperandSize::S32, 0x81, 4, dst, 0xffff, None)); // Mask to 16 bit diff --git a/src/verifier.rs b/src/verifier.rs index 06aec671b..db483568c 100644 --- a/src/verifier.rs +++ b/src/verifier.rs @@ -303,7 +303,7 @@ impl Verifier for RequisiteVerifier { ebpf::MOV32_REG => {}, ebpf::ARSH32_IMM => { check_imm_shift(&insn, insn_ptr, 32)?; }, ebpf::ARSH32_REG => {}, - ebpf::LE => { check_imm_endian(&insn, insn_ptr)?; }, + ebpf::LE if sbpf_version.enable_le() => { check_imm_endian(&insn, insn_ptr)?; }, ebpf::BE => { check_imm_endian(&insn, insn_ptr)?; }, // BPF_ALU64 class diff --git a/tests/execution.rs b/tests/execution.rs index 1b2d83d40..816700783 100644 --- a/tests/execution.rs +++ b/tests/execution.rs @@ -649,25 +649,27 @@ fn test_be64() { #[test] fn test_le16() { + let config = Config { + enable_sbpf_v2: false, + ..Config::default() + }; test_interpreter_and_jit_asm!( " ldxh r0, [r1] le16 r0 exit", + config, [0x22, 0x11], (), TestContextObject::new(3), ProgramResult::Ok(0x1122), ); -} - -#[test] -fn test_le16_high() { test_interpreter_and_jit_asm!( " ldxdw r0, [r1] le16 r0 exit", + config, [0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88], (), TestContextObject::new(3), @@ -677,25 +679,27 @@ fn test_le16_high() { #[test] fn test_le32() { + let config = Config { + enable_sbpf_v2: false, + ..Config::default() + }; test_interpreter_and_jit_asm!( " ldxw r0, [r1] le32 r0 exit", + config, [0x44, 0x33, 0x22, 0x11], (), TestContextObject::new(3), ProgramResult::Ok(0x11223344), ); -} - -#[test] -fn test_le32_high() { test_interpreter_and_jit_asm!( " ldxdw r0, [r1] le32 r0 exit", + config, [0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88], (), TestContextObject::new(3), @@ -705,11 +709,16 @@ fn test_le32_high() { #[test] fn test_le64() { + let config = Config { + enable_sbpf_v2: false, + ..Config::default() + }; test_interpreter_and_jit_asm!( " ldxdw r0, [r1] le64 r0 exit", + config, [0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11], (), TestContextObject::new(3),