-
Notifications
You must be signed in to change notification settings - Fork 259
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add an option to register allowed ranges of memory
Certain kernel helpers return pointers to kernel managed memory, which the ebpf program is allowed to load and read. In order to implement stubs for these using rbpf, we need a way to mark these ranges of memory as safe for the check_mem function. The API specifically deals with adresses, because helpers need to be function types and not closures. This means the pointers to objects returned from them need to be static, and dealing with references to static objects gets clunky. So I have chosen to push the obtaining of the addresses into calling code. Signed-off-by: Wouter Dullaert <[email protected]>
- Loading branch information
Showing
7 changed files
with
286 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -78,3 +78,6 @@ name = "to_json" | |
|
||
[[example]] | ||
name = "rbpf_plugin" | ||
|
||
[[example]] | ||
name = "allowed_memory" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
// SPDX-License-Identifier: (Apache-2.0 OR MIT) | ||
// Copyright 2024 Akenes SA <[email protected]> | ||
|
||
#![cfg_attr(feature = "cargo-clippy", allow(clippy::unreadable_literal))] | ||
|
||
extern crate elf; | ||
use std::{iter::FromIterator, ptr::addr_of}; | ||
|
||
extern crate rbpf; | ||
|
||
// The following example uses an ELF file that was compiled from the ebpf-allowed-memory.rs file | ||
// It is built using the [aya framework](https://aya-rs.dev/). | ||
// Once the aya dependencies (rust-nightly, latest llvm and latest bpf-linker) are installed, it | ||
// can be compiled via | ||
// | ||
// ```bash | ||
// cargo build --target=bpfel-unknown-none -Z build-std=core | ||
// ``` | ||
|
||
const BPF_MAP_LOOKUP_ELEM_IDX: u32 = 1; | ||
|
||
#[repr(C, packed)] | ||
#[derive(Clone, Copy)] | ||
pub struct Key { | ||
pub protocol: u8, | ||
} | ||
|
||
#[repr(C, packed)] | ||
pub struct Value { | ||
pub result: i32, | ||
} | ||
|
||
static MAP_VALUE: Value = Value { result: 1 }; | ||
|
||
fn bpf_lookup_elem(_map: u64, key_addr: u64, _flags: u64, _u4: u64, _u5: u64) -> u64 { | ||
let key: Key = unsafe { *(key_addr as *const Key) }; | ||
if key.protocol == 1 { | ||
return addr_of!(MAP_VALUE) as u64; | ||
} | ||
0 | ||
} | ||
|
||
fn main() { | ||
let file = elf::File::open_path("examples/allowed-memory.o").unwrap(); | ||
let func = file.get_section("classifier").unwrap(); | ||
|
||
let mut vm = rbpf::EbpfVmNoData::new(Some(&func.data)).unwrap(); | ||
vm.register_helper(BPF_MAP_LOOKUP_ELEM_IDX, bpf_lookup_elem) | ||
.unwrap(); | ||
|
||
let start = addr_of!(MAP_VALUE) as u64; | ||
let addrs = Vec::from_iter(start..start + size_of::<Value>() as u64); | ||
vm.register_allowed_memory(&addrs); | ||
|
||
let res = vm.execute_program().unwrap(); | ||
assert_eq!(res, 1); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
// SPDX-License-Identifier: (Apache-2.0 OR MIT) | ||
// Copyright 2024 Akenes SA <[email protected]> | ||
|
||
#![no_std] | ||
#![no_main] | ||
|
||
use aya_ebpf::{ | ||
bindings::{BPF_F_NO_PREALLOC, TC_ACT_PIPE}, | ||
macros::{classifier, map}, | ||
maps::HashMap, | ||
programs::TcContext, | ||
}; | ||
|
||
#[map] | ||
static RULES: HashMap<Key, Value> = HashMap::<Key, Value>::with_max_entries(1, BPF_F_NO_PREALLOC); | ||
|
||
#[repr(C, packed)] | ||
pub struct Key { | ||
pub protocol: u8, | ||
} | ||
|
||
#[repr(C, packed)] | ||
pub struct Value { | ||
pub result: i32, | ||
} | ||
|
||
#[classifier] | ||
pub fn ingress_tc(_ctx: TcContext) -> i32 { | ||
let key = Key { protocol: 1 }; | ||
if let Some(action) = unsafe { RULES.get(&key) } { | ||
return action.result; | ||
} | ||
return TC_ACT_PIPE; | ||
} | ||
|
||
#[panic_handler] | ||
fn panic(_info: &core::panic::PanicInfo) -> ! { | ||
unsafe { core::hint::unreachable_unchecked() } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.