Skip to content

Commit

Permalink
Gate call imm in sbpf v2
Browse files Browse the repository at this point in the history
  • Loading branch information
LucasSte committed Nov 4, 2024
1 parent 59dc13a commit 091230b
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 2 deletions.
4 changes: 3 additions & 1 deletion src/interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -528,7 +528,9 @@ impl<'a, 'b, C: ContextObject> Interpreter<'a, 'b, C> {
// Do not delegate the check to the verifier, since self.registered functions can be
// changed after the program has been verified.
ebpf::CALL_IMM => {
if let Some((_, function)) = self.executable.get_loader().get_function_registry(self.executable.get_sbpf_version()).lookup_by_key(insn.imm as u32) {
if let (false, Some((_, function))) =
(self.executable.get_sbpf_version().static_syscalls(),
self.executable.get_loader().get_function_registry(self.executable.get_sbpf_version()).lookup_by_key(insn.imm as u32)) {
// SBPFv1 syscall
self.reg[0] = match self.dispatch_syscall(function) {
ProgramResult::Ok(value) => *value,
Expand Down
4 changes: 3 additions & 1 deletion src/jit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -708,7 +708,9 @@ impl<'a, C: ContextObject> JitCompiler<'a, C> {
ebpf::JSLE_REG => self.emit_conditional_branch_reg(0x8e, false, src, dst, target_pc),
ebpf::CALL_IMM => {
// For JIT, external functions MUST be registered at compile time.
if let Some((_, function)) = self.executable.get_loader().get_function_registry(self.executable.get_sbpf_version()).lookup_by_key(insn.imm as u32) {
if let (false, Some((_, function))) =
(self.executable.get_sbpf_version().static_syscalls(),
self.executable.get_loader().get_function_registry(self.executable.get_sbpf_version()).lookup_by_key(insn.imm as u32)) {
// SBPFv1 syscall
self.emit_syscall_dispatch(function);
} else if let Some((_function_name, target_pc)) = self.executable.get_function_registry().lookup_by_key(insn.imm as u32) {
Expand Down
34 changes: 34 additions & 0 deletions tests/execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4088,6 +4088,40 @@ fn test_mod() {
);
}

#[test]
fn test_invalid_call_imm() {
// In SBPFv2, `call_imm` N shall not be dispatched to a syscall.
let prog = &[
0x85, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, // call_imm 2
0x9d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
];

let config = Config {
enabled_sbpf_versions: SBPFVersion::V2..=SBPFVersion::V2,
enable_instruction_tracing: true,
..Config::default()
};
let mut loader = BuiltinProgram::new_loader_with_dense_registration(config);
loader
.register_function("syscall_string", 2, syscalls::SyscallString::vm)
.unwrap();
let mut executable = Executable::<TestContextObject>::from_text_bytes(
prog,
Arc::new(loader),
SBPFVersion::V2,
FunctionRegistry::default(),
)
.unwrap();

test_interpreter_and_jit!(
false,
executable,
[],
TestContextObject::new(1),
ProgramResult::Err(EbpfError::UnsupportedInstruction),
);
}

#[test]
#[should_panic(expected = "Invalid syscall should have been detected in the verifier.")]
fn test_invalid_exit_or_return() {
Expand Down

0 comments on commit 091230b

Please sign in to comment.