Skip to content

Commit a8716e9

Browse files
committed
src/interpreter.rs: Use wrapping_offset() for load/store operations
Rust 1.83 introduces some additional out-of-bound checks [0], making it illegal to attempt to load at an out-of-bound access when trying to load/store values from/to register in rbpf's interpreter, and causing the program to panick even before we reach the safety checks from check_mem(). I understand we need to use wrapping_offset() rather than offset() in that case, which causes the operation itself (but not the resulting poitner) to be safe, and the checked to be deferred. See also the related GitHub issue [1]. [0] rust-lang/rust#130251 [1] #115 Reported-by: Ben Kimock <kimockb@gmail.com> Signed-off-by: Quentin Monnet <qmo@qmon.net>
1 parent 93e7dcd commit a8716e9

File tree

1 file changed

+12
-12
lines changed

1 file changed

+12
-12
lines changed

src/interpreter.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -139,75 +139,75 @@ pub fn execute_program(
139139
// BPF_LDX class
140140
ebpf::LD_B_REG => reg[_dst] = unsafe {
141141
#[allow(clippy::cast_ptr_alignment)]
142-
let x = (reg[_src] as *const u8).offset(insn.off as isize) as *const u8;
142+
let x = (reg[_src] as *const u8).wrapping_offset(insn.off as isize) as *const u8;
143143
check_mem_load(x as u64, 1, insn_ptr)?;
144144
x.read_unaligned() as u64
145145
},
146146
ebpf::LD_H_REG => reg[_dst] = unsafe {
147147
#[allow(clippy::cast_ptr_alignment)]
148-
let x = (reg[_src] as *const u8).offset(insn.off as isize) as *const u16;
148+
let x = (reg[_src] as *const u8).wrapping_offset(insn.off as isize) as *const u16;
149149
check_mem_load(x as u64, 2, insn_ptr)?;
150150
x.read_unaligned() as u64
151151
},
152152
ebpf::LD_W_REG => reg[_dst] = unsafe {
153153
#[allow(clippy::cast_ptr_alignment)]
154-
let x = (reg[_src] as *const u8).offset(insn.off as isize) as *const u32;
154+
let x = (reg[_src] as *const u8).wrapping_offset(insn.off as isize) as *const u32;
155155
check_mem_load(x as u64, 4, insn_ptr)?;
156156
x.read_unaligned() as u64
157157
},
158158
ebpf::LD_DW_REG => reg[_dst] = unsafe {
159159
#[allow(clippy::cast_ptr_alignment)]
160-
let x = (reg[_src] as *const u8).offset(insn.off as isize) as *const u64;
160+
let x = (reg[_src] as *const u8).wrapping_offset(insn.off as isize) as *const u64;
161161
check_mem_load(x as u64, 8, insn_ptr)?;
162162
x.read_unaligned()
163163
},
164164

165165
// BPF_ST class
166166
ebpf::ST_B_IMM => unsafe {
167-
let x = (reg[_dst] as *const u8).offset(insn.off as isize) as *mut u8;
167+
let x = (reg[_dst] as *const u8).wrapping_offset(insn.off as isize) as *mut u8;
168168
check_mem_store(x as u64, 1, insn_ptr)?;
169169
x.write_unaligned(insn.imm as u8);
170170
},
171171
ebpf::ST_H_IMM => unsafe {
172172
#[allow(clippy::cast_ptr_alignment)]
173-
let x = (reg[_dst] as *const u8).offset(insn.off as isize) as *mut u16;
173+
let x = (reg[_dst] as *const u8).wrapping_offset(insn.off as isize) as *mut u16;
174174
check_mem_store(x as u64, 2, insn_ptr)?;
175175
x.write_unaligned(insn.imm as u16);
176176
},
177177
ebpf::ST_W_IMM => unsafe {
178178
#[allow(clippy::cast_ptr_alignment)]
179-
let x = (reg[_dst] as *const u8).offset(insn.off as isize) as *mut u32;
179+
let x = (reg[_dst] as *const u8).wrapping_offset(insn.off as isize) as *mut u32;
180180
check_mem_store(x as u64, 4, insn_ptr)?;
181181
x.write_unaligned(insn.imm as u32);
182182
},
183183
ebpf::ST_DW_IMM => unsafe {
184184
#[allow(clippy::cast_ptr_alignment)]
185-
let x = (reg[_dst] as *const u8).offset(insn.off as isize) as *mut u64;
185+
let x = (reg[_dst] as *const u8).wrapping_offset(insn.off as isize) as *mut u64;
186186
check_mem_store(x as u64, 8, insn_ptr)?;
187187
x.write_unaligned(insn.imm as u64);
188188
},
189189

190190
// BPF_STX class
191191
ebpf::ST_B_REG => unsafe {
192-
let x = (reg[_dst] as *const u8).offset(insn.off as isize) as *mut u8;
192+
let x = (reg[_dst] as *const u8).wrapping_offset(insn.off as isize) as *mut u8;
193193
check_mem_store(x as u64, 1, insn_ptr)?;
194194
x.write_unaligned(reg[_src] as u8);
195195
},
196196
ebpf::ST_H_REG => unsafe {
197197
#[allow(clippy::cast_ptr_alignment)]
198-
let x = (reg[_dst] as *const u8).offset(insn.off as isize) as *mut u16;
198+
let x = (reg[_dst] as *const u8).wrapping_offset(insn.off as isize) as *mut u16;
199199
check_mem_store(x as u64, 2, insn_ptr)?;
200200
x.write_unaligned(reg[_src] as u16);
201201
},
202202
ebpf::ST_W_REG => unsafe {
203203
#[allow(clippy::cast_ptr_alignment)]
204-
let x = (reg[_dst] as *const u8).offset(insn.off as isize) as *mut u32;
204+
let x = (reg[_dst] as *const u8).wrapping_offset(insn.off as isize) as *mut u32;
205205
check_mem_store(x as u64, 4, insn_ptr)?;
206206
x.write_unaligned(reg[_src] as u32);
207207
},
208208
ebpf::ST_DW_REG => unsafe {
209209
#[allow(clippy::cast_ptr_alignment)]
210-
let x = (reg[_dst] as *const u8).offset(insn.off as isize) as *mut u64;
210+
let x = (reg[_dst] as *const u8).wrapping_offset(insn.off as isize) as *mut u64;
211211
check_mem_store(x as u64, 8, insn_ptr)?;
212212
x.write_unaligned(reg[_src]);
213213
},

0 commit comments

Comments
 (0)