4
0

bpf_probe_read.rs 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. #![no_std]
  2. #![no_main]
  3. use aya_ebpf::{
  4. helpers::{bpf_probe_read_kernel_str_bytes, bpf_probe_read_user_str_bytes},
  5. macros::{map, uprobe},
  6. maps::Array,
  7. programs::ProbeContext,
  8. };
  9. use integration_common::bpf_probe_read::{RESULT_BUF_LEN, TestResult};
  10. #[cfg(not(test))]
  11. extern crate ebpf_panic;
  12. fn read_str_bytes(
  13. fun: unsafe fn(*const u8, &mut [u8]) -> Result<&[u8], i64>,
  14. iptr: Option<*const u8>,
  15. ilen: Option<usize>,
  16. ) {
  17. let Some(iptr) = iptr else {
  18. return;
  19. };
  20. let Some(ilen) = ilen else {
  21. return;
  22. };
  23. let Some(ptr) = RESULT.get_ptr_mut(0) else {
  24. return;
  25. };
  26. let dst = unsafe { ptr.as_mut() };
  27. let Some(TestResult { buf, len }) = dst else {
  28. return;
  29. };
  30. *len = None;
  31. // len comes from ctx.arg(1) so it's dynamic and the verifier doesn't see any bounds. We slice
  32. // here to ensure that the verifier can see the upper bound, or you get:
  33. //
  34. // 18: (79) r7 = *(u64 *)(r7 +8) ; R7_w=scalar()
  35. // [snip]
  36. // 27: (bf) r2 = r7 ;
  37. // R2_w=scalar(id=2,umax=9223372036854775807,var_off=(0x0; 0x7fffffffffffffff)) [snip]
  38. // 28: (85) call bpf_probe_read_user_str#114
  39. // R2 unbounded memory access, use 'var &= const' or 'if (var < const)'
  40. let Some(buf) = buf.get_mut(..ilen) else {
  41. return;
  42. };
  43. *len = Some(unsafe { fun(iptr, buf) }.map(<[_]>::len));
  44. }
  45. #[map]
  46. static RESULT: Array<TestResult> = Array::with_max_entries(1, 0);
  47. #[map]
  48. static KERNEL_BUFFER: Array<[u8; RESULT_BUF_LEN]> = Array::with_max_entries(1, 0);
  49. #[uprobe]
  50. pub fn test_bpf_probe_read_user_str_bytes(ctx: ProbeContext) {
  51. read_str_bytes(
  52. bpf_probe_read_user_str_bytes,
  53. ctx.arg::<*const u8>(0),
  54. ctx.arg::<usize>(1),
  55. );
  56. }
  57. #[uprobe]
  58. pub fn test_bpf_probe_read_kernel_str_bytes(ctx: ProbeContext) {
  59. read_str_bytes(
  60. bpf_probe_read_kernel_str_bytes,
  61. KERNEL_BUFFER
  62. .get_ptr(0)
  63. .and_then(|ptr| unsafe { ptr.as_ref() })
  64. .map(|buf| buf.as_ptr()),
  65. ctx.arg::<usize>(0),
  66. );
  67. }