@@ -254,8 +254,8 @@ pub fn execute_program(
254254 check_mem_store ( x as u64 , 8 , insn_ptr) ?;
255255 x. write_unaligned ( reg[ _src] ) ;
256256 } ,
257- ebpf:: ST_W_XADD => unimplemented ! ( ) ,
258- ebpf:: ST_DW_XADD => unimplemented ! ( ) ,
257+ ebpf:: ST_W_XADD => Err ( Error :: other ( format ! ( "Error: XADD instructions are not supported (insn #{})" , insn_ptr - 1 ) ) ) ? ,
258+ ebpf:: ST_DW_XADD => Err ( Error :: other ( format ! ( "Error: XADD instructions are not supported (insn #{})" , insn_ptr - 1 ) ) ) ? ,
259259
260260 // BPF_ALU class
261261 // TODO Check how overflow works in kernel. Should we &= U32MAX all src register value
@@ -427,7 +427,25 @@ pub fn execute_program(
427427 // that read or write to the stack, check_mem_load or check_mem_store will return an error.
428428 reg[ 10 ] -= stacks[ stack_frame_idx] . get_stack_usage ( ) . stack_usage ( ) as u64 ;
429429 stack_frame_idx += 1 ;
430- insn_ptr += insn. imm as usize ;
430+ // Use checked arithmetic to prevent integer overflow
431+ let offset = insn. imm as isize ;
432+ if offset < 0 {
433+ let abs_offset = ( -offset) as usize ;
434+ if abs_offset > insn_ptr {
435+ Err ( Error :: other ( format ! (
436+ "Error: call offset underflow (insn #{})" ,
437+ insn_ptr - 1
438+ ) ) ) ?;
439+ }
440+ insn_ptr -= abs_offset;
441+ } else {
442+ insn_ptr = insn_ptr. checked_add ( offset as usize ) . ok_or_else ( || {
443+ Error :: other ( format ! (
444+ "Error: call offset overflow (insn #{})" ,
445+ insn_ptr - 1
446+ ) )
447+ } ) ?;
448+ }
431449 }
432450 _ => {
433451 Err ( Error :: other (
@@ -439,7 +457,7 @@ pub fn execute_program(
439457 }
440458 }
441459 }
442- ebpf:: TAIL_CALL => unimplemented ! ( ) ,
460+ ebpf:: TAIL_CALL => Err ( Error :: other ( format ! ( "Error: TAIL_CALL is not supported (insn #{})" , insn_ptr - 1 ) ) ) ? ,
443461 ebpf:: EXIT => {
444462 if stack_frame_idx > 0 {
445463 stack_frame_idx -= 1 ;
0 commit comments