allowed_memory.rs 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. // SPDX-License-Identifier: (Apache-2.0 OR MIT)
  2. // Copyright 2024 Akenes SA <wouter.dullaert@exoscale.ch>
  3. #![cfg_attr(feature = "cargo-clippy", allow(clippy::unreadable_literal))]
  4. extern crate elf;
  5. use std::{iter::FromIterator, ptr::addr_of};
  6. extern crate rbpf;
  7. // The following example uses an ELF file that was compiled from the ebpf-allowed-memory.rs file
  8. // It is built using the [aya framework](https://aya-rs.dev/).
  9. // Once the aya dependencies (rust-nightly, latest llvm and latest bpf-linker) are installed, it
  10. // can be compiled via
  11. //
  12. // ```bash
  13. // cargo build --target=bpfel-unknown-none -Z build-std=core
  14. // ```
  15. const BPF_MAP_LOOKUP_ELEM_IDX: u32 = 1;
  16. #[repr(C, packed)]
  17. #[derive(Clone, Copy)]
  18. pub struct Key {
  19. pub protocol: u8,
  20. }
  21. #[repr(C, packed)]
  22. pub struct Value {
  23. pub result: i32,
  24. }
  25. static MAP_VALUE: Value = Value { result: 1 };
  26. fn bpf_lookup_elem(_map: u64, key_addr: u64, _flags: u64, _u4: u64, _u5: u64) -> u64 {
  27. let key: Key = unsafe { *(key_addr as *const Key) };
  28. if key.protocol == 1 {
  29. return addr_of!(MAP_VALUE) as u64;
  30. }
  31. 0
  32. }
  33. fn main() {
  34. let file = elf::File::open_path("examples/allowed-memory.o").unwrap();
  35. let func = file.get_section("classifier").unwrap();
  36. let mut vm = rbpf::EbpfVmNoData::new(Some(&func.data)).unwrap();
  37. vm.register_helper(BPF_MAP_LOOKUP_ELEM_IDX, bpf_lookup_elem)
  38. .unwrap();
  39. let start = addr_of!(MAP_VALUE) as u64;
  40. let addrs = Vec::from_iter(start..start + size_of::<Value>() as u64);
  41. vm.register_allowed_memory(&addrs);
  42. let res = vm.execute_program().unwrap();
  43. assert_eq!(res, 1);
  44. }