Skip to content

Commit 03c7289

Browse files
committed
feat: Use Range to indicate the memory range that is allowed to be accessed
Since some maps may store a lot of data, representing the address with a single byte may waste a lot of space. Using range can simplify this problem. Signed-off-by: Godones <[email protected]>
1 parent 69c5c5c commit 03c7289

File tree

4 files changed

+21
-30
lines changed

4 files changed

+21
-30
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ useful for programs that should be compatible with the Linux kernel and
210210
therefore must use specific helper numbers.
211211

212212
```rust,ignore
213-
pub fn register_allowed_memory(&mut self,, addr: &[u64]) -> ()
213+
pub fn register_allowed_memory(&mut self,, addrs_range: Range<u64>) -> ()
214214
```
215215

216216
This function adds a list of memory addresses that the eBPF program is allowed

examples/allowed_memory.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Copyright 2024 Akenes SA <[email protected]>
33

44
extern crate elf;
5-
use std::{iter::FromIterator, ptr::addr_of};
5+
use std::{ptr::addr_of};
66

77
extern crate rbpf;
88

@@ -40,8 +40,7 @@ fn main() {
4040
.unwrap();
4141

4242
let start = addr_of!(MAP_VALUE) as u64;
43-
let addrs = Vec::from_iter(start..start + size_of::<Value>() as u64);
44-
vm.register_allowed_memory(&addrs);
43+
vm.register_allowed_memory(start..start + size_of::<Value>() as u64);
4544

4645
let res = vm.execute_program().unwrap();
4746
assert_eq!(res, 1);

src/interpreter.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use crate::ebpf;
99
use crate::ebpf::MAX_CALL_DEPTH;
1010
use crate::lib::*;
1111
use crate::stack::{StackFrame, StackUsage};
12+
use core::ops::Range;
1213

1314
#[allow(clippy::too_many_arguments)]
1415
fn check_mem(
@@ -19,7 +20,7 @@ fn check_mem(
1920
mbuff: &[u8],
2021
mem: &[u8],
2122
stack: &[u8],
22-
allowed_memory: &HashSet<u64>,
23+
allowed_memory: &HashSet<Range<u64>>,
2324
) -> Result<(), Error> {
2425
if let Some(addr_end) = addr.checked_add(len as u64) {
2526
if mbuff.as_ptr() as u64 <= addr && addr_end <= mbuff.as_ptr() as u64 + mbuff.len() as u64 {
@@ -31,7 +32,7 @@ fn check_mem(
3132
if stack.as_ptr() as u64 <= addr && addr_end <= stack.as_ptr() as u64 + stack.len() as u64 {
3233
return Ok(());
3334
}
34-
if allowed_memory.contains(&addr) {
35+
if allowed_memory.iter().any(|range| range.contains(&addr)) {
3536
return Ok(());
3637
}
3738
}
@@ -51,7 +52,7 @@ pub fn execute_program(
5152
mem: &[u8],
5253
mbuff: &[u8],
5354
helpers: &HashMap<u32, ebpf::Helper>,
54-
allowed_memory: &HashSet<u64>,
55+
allowed_memory: &HashSet<Range<u64>>,
5556
) -> Result<u64, Error> {
5657
const U32MAX: u64 = u32::MAX as u64;
5758
const SHIFT_MASK_64: u64 = 0x3f;

src/lib.rs

Lines changed: 14 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ extern crate cranelift_native;
3535

3636
use crate::lib::*;
3737
use byteorder::{ByteOrder, LittleEndian};
38+
use core::ops::Range;
3839
use stack::{StackUsage, StackVerifier};
3940

4041
mod asm_parser;
@@ -180,7 +181,7 @@ pub struct EbpfVmMbuff<'a> {
180181
#[cfg(feature = "cranelift")]
181182
cranelift_prog: Option<cranelift::CraneliftProgram>,
182183
helpers: HashMap<u32, ebpf::Helper>,
183-
allowed_memory: HashSet<u64>,
184+
allowed_memory: HashSet<Range<u64>>,
184185
stack_usage: Option<StackUsage>,
185186
stack_verifier: StackVerifier,
186187
}
@@ -400,7 +401,6 @@ impl<'a> EbpfVmMbuff<'a> {
400401
/// # Examples
401402
///
402403
/// ```
403-
/// use std::iter::FromIterator;
404404
/// use std::ptr::addr_of;
405405
///
406406
/// struct MapValue {
@@ -416,13 +416,10 @@ impl<'a> EbpfVmMbuff<'a> {
416416
/// // Instantiate a VM.
417417
/// let mut vm = rbpf::EbpfVmMbuff::new(Some(prog)).unwrap();
418418
/// let start = addr_of!(VALUE) as u64;
419-
/// let addrs = Vec::from_iter(start..start+size_of::<MapValue>() as u64);
420-
/// vm.register_allowed_memory(&addrs);
419+
/// vm.register_allowed_memory(start..start+size_of::<MapValue>() as u64);
421420
/// ```
422-
pub fn register_allowed_memory(&mut self, addrs: &[u64]) {
423-
for i in addrs {
424-
self.allowed_memory.insert(*i);
425-
}
421+
pub fn register_allowed_memory(&mut self, addrs_range: Range<u64>) {
422+
self.allowed_memory.insert(addrs_range);
426423
}
427424

428425
/// Execute the program loaded, with the given packet data and metadata buffer.
@@ -1025,7 +1022,6 @@ impl<'a> EbpfVmFixedMbuff<'a> {
10251022
/// # Examples
10261023
///
10271024
/// ```
1028-
/// use std::iter::FromIterator;
10291025
/// use std::ptr::addr_of;
10301026
///
10311027
/// struct MapValue {
@@ -1041,11 +1037,10 @@ impl<'a> EbpfVmFixedMbuff<'a> {
10411037
/// // Instantiate a VM.
10421038
/// let mut vm = rbpf::EbpfVmFixedMbuff::new(Some(prog), 0x40, 0x50).unwrap();
10431039
/// let start = addr_of!(VALUE) as u64;
1044-
/// let addrs = Vec::from_iter(start..start+size_of::<MapValue>() as u64);
1045-
/// vm.register_allowed_memory(&addrs);
1040+
/// vm.register_allowed_memory(start..start+size_of::<MapValue>() as u64);
10461041
/// ```
1047-
pub fn register_allowed_memory(&mut self, allowed: &[u64]) {
1048-
self.parent.register_allowed_memory(allowed)
1042+
pub fn register_allowed_memory(&mut self, addrs_range: Range<u64>) {
1043+
self.parent.register_allowed_memory(addrs_range)
10491044
}
10501045

10511046
/// Execute the program loaded, with the given packet data.
@@ -1568,7 +1563,6 @@ impl<'a> EbpfVmRaw<'a> {
15681563
/// # Examples
15691564
///
15701565
/// ```
1571-
/// use std::iter::FromIterator;
15721566
/// use std::ptr::addr_of;
15731567
///
15741568
/// struct MapValue {
@@ -1584,11 +1578,10 @@ impl<'a> EbpfVmRaw<'a> {
15841578
/// // Instantiate a VM.
15851579
/// let mut vm = rbpf::EbpfVmRaw::new(Some(prog)).unwrap();
15861580
/// let start = addr_of!(VALUE) as u64;
1587-
/// let addrs = Vec::from_iter(start..start+size_of::<MapValue>() as u64);
1588-
/// vm.register_allowed_memory(&addrs);
1581+
/// vm.register_allowed_memory(start..start+size_of::<MapValue>() as u64);
15891582
/// ```
1590-
pub fn register_allowed_memory(&mut self, allowed: &[u64]) {
1591-
self.parent.register_allowed_memory(allowed)
1583+
pub fn register_allowed_memory(&mut self, addrs_range: Range<u64>) {
1584+
self.parent.register_allowed_memory(addrs_range)
15921585
}
15931586

15941587
/// Execute the program loaded, with the given packet data.
@@ -2019,7 +2012,6 @@ impl<'a> EbpfVmNoData<'a> {
20192012
/// # Examples
20202013
///
20212014
/// ```
2022-
/// use std::iter::FromIterator;
20232015
/// use std::ptr::addr_of;
20242016
///
20252017
/// struct MapValue {
@@ -2035,11 +2027,10 @@ impl<'a> EbpfVmNoData<'a> {
20352027
/// // Instantiate a VM.
20362028
/// let mut vm = rbpf::EbpfVmNoData::new(Some(prog)).unwrap();
20372029
/// let start = addr_of!(VALUE) as u64;
2038-
/// let addrs = Vec::from_iter(start..start+size_of::<MapValue>() as u64);
2039-
/// vm.register_allowed_memory(&addrs);
2030+
/// vm.register_allowed_memory(start..start+size_of::<MapValue>() as u64);
20402031
/// ```
2041-
pub fn register_allowed_memory(&mut self, allowed: &[u64]) {
2042-
self.parent.register_allowed_memory(allowed)
2032+
pub fn register_allowed_memory(&mut self, addrs_range: Range<u64>) {
2033+
self.parent.register_allowed_memory(addrs_range)
20432034
}
20442035

20452036
/// JIT-compile the loaded program. No argument required for this.

0 commit comments

Comments
 (0)