lsm.rs 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. use core::ffi::c_void;
  2. use crate::{args::FromBtfArgument, EbpfContext};
  3. pub struct LsmContext {
  4. ctx: *mut c_void,
  5. }
  6. impl LsmContext {
  7. pub fn new(ctx: *mut c_void) -> LsmContext {
  8. LsmContext { ctx }
  9. }
  10. /// Returns the `n`th argument passed to the LSM hook, starting from 0.
  11. ///
  12. /// You can refer to [the kernel's list of LSM hook definitions][1] to find the
  13. /// appropriate argument list for your LSM hook, where the argument list starts
  14. /// _after_ the third parameter to the kernel's `LSM_HOOK` macro.
  15. ///
  16. /// LSM probes specifically have access to an additional argument `retval: int`
  17. /// which provides the return value of the previous LSM program that was called on
  18. /// this code path, or 0 if this is the first LSM program to be called. This phony
  19. /// argument is always last in the argument list.
  20. ///
  21. /// SAFETY: This function is deeply unsafe, as we are reading raw pointers into kernel memory.
  22. /// In particular, the value of `n` must not exceed the number of function arguments.
  23. /// Luckily, the BPF verifier will catch this for us.
  24. ///
  25. /// # Examples
  26. ///
  27. /// ```no_run
  28. /// # #![allow(dead_code)]
  29. /// # use aya_ebpf::{programs::LsmContext, cty::{c_int, c_ulong}};
  30. /// unsafe fn try_lsm_mmap_addr(ctx: LsmContext) -> Result<i32, i32> {
  31. /// // In the kernel, this hook is defined as:
  32. /// // LSM_HOOK(int, 0, mmap_addr, unsigned long addr)
  33. /// let addr: c_ulong = ctx.arg(0);
  34. /// let retval: c_int = ctx.arg(1);
  35. ///
  36. /// // You can then do stuff with addr and retval down here.
  37. ///
  38. /// // To practice good LSM hygiene, let's defer to a previous retval
  39. /// // if available:
  40. /// if (retval != 0) {
  41. /// return Ok(retval);
  42. /// }
  43. ///
  44. /// Ok(0)
  45. /// }
  46. /// ```
  47. ///
  48. /// [1]: https://elixir.bootlin.com/linux/latest/source/include/linux/lsm_hook_defs.h
  49. pub unsafe fn arg<T: FromBtfArgument>(&self, n: usize) -> T {
  50. T::from_argument(self.ctx as *const _, n)
  51. }
  52. }
  53. impl EbpfContext for LsmContext {
  54. fn as_ptr(&self) -> *mut c_void {
  55. self.ctx
  56. }
  57. }