helpers.rs 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844
  1. //! This module contains kernel helper functions that may be exposed to specific
  2. //! BPF program types.
  3. //!
  4. //! These helpers can be used to perform common tasks, query and operate on data
  5. //! exposed by the kernel, and perform some operations that would normally be
  6. //! denied by the BPF verifier.
  7. //!
  8. //! Here, we provide some higher-level wrappers around the underlying kernel
  9. //! helpers, but also expose bindings to the underlying helpers as a fall-back
  10. //! in case of a missing implementation.
  11. use core::{
  12. cmp::Ordering,
  13. ffi::CStr,
  14. mem::{self, MaybeUninit},
  15. };
  16. pub use aya_ebpf_bindings::helpers as generated;
  17. #[doc(hidden)]
  18. pub use generated::*;
  19. use crate::{
  20. check_bounds_signed,
  21. cty::{c_char, c_long, c_void},
  22. };
  23. /// Read bytes stored at `src` and store them as a `T`.
  24. ///
  25. /// Generally speaking, the more specific [`bpf_probe_read_user`] and
  26. /// [`bpf_probe_read_kernel`] should be preferred over this function.
  27. ///
  28. /// Returns a bitwise copy of `mem::size_of::<T>()` bytes stored at the user space address
  29. /// `src`. See `bpf_probe_read_kernel` for reading kernel space memory.
  30. ///
  31. /// # Examples
  32. ///
  33. /// ```no_run
  34. /// # #![expect(dead_code)]
  35. /// # use aya_ebpf::{cty::{c_int, c_long}, helpers::bpf_probe_read};
  36. /// # fn try_test() -> Result<(), c_long> {
  37. /// # let kernel_ptr: *const c_int = 0 as _;
  38. /// let my_int: c_int = unsafe { bpf_probe_read(kernel_ptr)? };
  39. ///
  40. /// // Do something with my_int
  41. /// # Ok::<(), c_long>(())
  42. /// # }
  43. /// ```
  44. ///
  45. /// # Errors
  46. ///
  47. /// On failure, this function returns a negative value wrapped in an `Err`.
  48. #[inline]
  49. pub unsafe fn bpf_probe_read<T>(src: *const T) -> Result<T, c_long> {
  50. let mut v: MaybeUninit<T> = MaybeUninit::uninit();
  51. let ret = generated::bpf_probe_read(
  52. v.as_mut_ptr() as *mut c_void,
  53. mem::size_of::<T>() as u32,
  54. src as *const c_void,
  55. );
  56. if ret == 0 {
  57. Ok(v.assume_init())
  58. } else {
  59. Err(ret)
  60. }
  61. }
  62. /// Read bytes from the pointer `src` into the provided destination buffer.
  63. ///
  64. /// Generally speaking, the more specific [`bpf_probe_read_user_buf`] and
  65. /// [`bpf_probe_read_kernel_buf`] should be preferred over this function.
  66. ///
  67. /// # Examples
  68. ///
  69. /// ```no_run
  70. /// # #![expect(dead_code)]
  71. /// # use aya_ebpf::{cty::{c_int, c_long}, helpers::bpf_probe_read_buf};
  72. /// # fn try_test() -> Result<(), c_long> {
  73. /// # let ptr: *const u8 = 0 as _;
  74. /// let mut buf = [0u8; 16];
  75. /// unsafe { bpf_probe_read_buf(ptr, &mut buf)? };
  76. ///
  77. /// # Ok::<(), c_long>(())
  78. /// # }
  79. /// ```
  80. ///
  81. /// # Errors
  82. ///
  83. /// On failure, this function returns a negative value wrapped in an `Err`.
  84. #[inline]
  85. pub unsafe fn bpf_probe_read_buf(src: *const u8, dst: &mut [u8]) -> Result<(), c_long> {
  86. let ret = generated::bpf_probe_read(
  87. dst.as_mut_ptr() as *mut c_void,
  88. dst.len() as u32,
  89. src as *const c_void,
  90. );
  91. if ret == 0 { Ok(()) } else { Err(ret) }
  92. }
  93. /// Read bytes stored at the _user space_ pointer `src` and store them as a `T`.
  94. ///
  95. /// Returns a bitwise copy of `mem::size_of::<T>()` bytes stored at the user space address
  96. /// `src`. See `bpf_probe_read_kernel` for reading kernel space memory.
  97. ///
  98. /// # Examples
  99. ///
  100. /// ```no_run
  101. /// # #![expect(dead_code)]
  102. /// # use aya_ebpf::{cty::{c_int, c_long}, helpers::bpf_probe_read_user};
  103. /// # fn try_test() -> Result<(), c_long> {
  104. /// # let user_ptr: *const c_int = 0 as _;
  105. /// let my_int: c_int = unsafe { bpf_probe_read_user(user_ptr)? };
  106. ///
  107. /// // Do something with my_int
  108. /// # Ok::<(), c_long>(())
  109. /// # }
  110. /// ```
  111. ///
  112. /// # Errors
  113. ///
  114. /// On failure, this function returns a negative value wrapped in an `Err`.
  115. #[inline]
  116. pub unsafe fn bpf_probe_read_user<T>(src: *const T) -> Result<T, c_long> {
  117. let mut v: MaybeUninit<T> = MaybeUninit::uninit();
  118. let ret = generated::bpf_probe_read_user(
  119. v.as_mut_ptr() as *mut c_void,
  120. mem::size_of::<T>() as u32,
  121. src as *const c_void,
  122. );
  123. if ret == 0 {
  124. Ok(v.assume_init())
  125. } else {
  126. Err(ret)
  127. }
  128. }
  129. /// Read bytes from the _user space_ pointer `src` into the provided destination
  130. /// buffer.
  131. ///
  132. /// # Examples
  133. ///
  134. /// ```no_run
  135. /// # #![expect(dead_code)]
  136. /// # use aya_ebpf::{cty::{c_int, c_long}, helpers::bpf_probe_read_user_buf};
  137. /// # fn try_test() -> Result<(), c_long> {
  138. /// # let user_ptr: *const u8 = 0 as _;
  139. /// let mut buf = [0u8; 16];
  140. /// unsafe { bpf_probe_read_user_buf(user_ptr, &mut buf)? };
  141. ///
  142. /// # Ok::<(), c_long>(())
  143. /// # }
  144. /// ```
  145. ///
  146. /// # Errors
  147. ///
  148. /// On failure, this function returns a negative value wrapped in an `Err`.
  149. #[inline]
  150. pub unsafe fn bpf_probe_read_user_buf(src: *const u8, dst: &mut [u8]) -> Result<(), c_long> {
  151. let ret = generated::bpf_probe_read_user(
  152. dst.as_mut_ptr() as *mut c_void,
  153. dst.len() as u32,
  154. src as *const c_void,
  155. );
  156. if ret == 0 { Ok(()) } else { Err(ret) }
  157. }
  158. /// Read bytes stored at the _kernel space_ pointer `src` and store them as a `T`.
  159. ///
  160. /// Returns a bitwise copy of `mem::size_of::<T>()` bytes stored at the kernel space address
  161. /// `src`. See `bpf_probe_read_user` for reading user space memory.
  162. ///
  163. /// # Examples
  164. ///
  165. /// ```no_run
  166. /// # #![expect(dead_code)]
  167. /// # use aya_ebpf::{cty::{c_int, c_long}, helpers::bpf_probe_read_kernel};
  168. /// # fn try_test() -> Result<(), c_long> {
  169. /// # let kernel_ptr: *const c_int = 0 as _;
  170. /// let my_int: c_int = unsafe { bpf_probe_read_kernel(kernel_ptr)? };
  171. ///
  172. /// // Do something with my_int
  173. /// # Ok::<(), c_long>(())
  174. /// # }
  175. /// ```
  176. ///
  177. /// # Errors
  178. ///
  179. /// On failure, this function returns a negative value wrapped in an `Err`.
  180. #[inline]
  181. pub unsafe fn bpf_probe_read_kernel<T>(src: *const T) -> Result<T, c_long> {
  182. let mut v: MaybeUninit<T> = MaybeUninit::uninit();
  183. let ret = generated::bpf_probe_read_kernel(
  184. v.as_mut_ptr() as *mut c_void,
  185. mem::size_of::<T>() as u32,
  186. src as *const c_void,
  187. );
  188. if ret == 0 {
  189. Ok(v.assume_init())
  190. } else {
  191. Err(ret)
  192. }
  193. }
  194. /// Read bytes from the _kernel space_ pointer `src` into the provided destination
  195. /// buffer.
  196. ///
  197. /// # Examples
  198. ///
  199. /// ```no_run
  200. /// # #![expect(dead_code)]
  201. /// # use aya_ebpf::{cty::{c_int, c_long}, helpers::bpf_probe_read_kernel_buf};
  202. /// # fn try_test() -> Result<(), c_long> {
  203. /// # let kernel_ptr: *const u8 = 0 as _;
  204. /// let mut buf = [0u8; 16];
  205. /// unsafe { bpf_probe_read_kernel_buf(kernel_ptr, &mut buf)? };
  206. ///
  207. /// # Ok::<(), c_long>(())
  208. /// # }
  209. /// ```
  210. ///
  211. /// # Errors
  212. ///
  213. /// On failure, this function returns a negative value wrapped in an `Err`.
  214. #[inline]
  215. pub unsafe fn bpf_probe_read_kernel_buf(src: *const u8, dst: &mut [u8]) -> Result<(), c_long> {
  216. let ret = generated::bpf_probe_read_kernel(
  217. dst.as_mut_ptr() as *mut c_void,
  218. dst.len() as u32,
  219. src as *const c_void,
  220. );
  221. if ret == 0 { Ok(()) } else { Err(ret) }
  222. }
  223. /// Read a null-terminated string stored at `src` into `dest`.
  224. ///
  225. /// Generally speaking, the more specific [`bpf_probe_read_user_str`] and
  226. /// [`bpf_probe_read_kernel_str`] should be preferred over this function.
  227. ///
  228. /// In case the length of `dest` is smaller then the length of `src`, the read bytes will
  229. /// be truncated to the size of `dest`.
  230. ///
  231. /// # Examples
  232. ///
  233. /// ```no_run
  234. /// # #![expect(dead_code)]
  235. /// # use aya_ebpf::{cty::c_long, helpers::bpf_probe_read_str};
  236. /// # fn try_test() -> Result<(), c_long> {
  237. /// # let kernel_ptr: *const u8 = 0 as _;
  238. /// let mut my_str = [0u8; 16];
  239. /// let num_read = unsafe { bpf_probe_read_str(kernel_ptr, &mut my_str)? };
  240. ///
  241. /// // Do something with num_read and my_str
  242. /// # Ok::<(), c_long>(())
  243. /// # }
  244. /// ```
  245. ///
  246. /// # Errors
  247. ///
  248. /// On failure, this function returns Err(-1).
  249. #[deprecated(
  250. note = "Use `bpf_probe_read_user_str_bytes` or `bpf_probe_read_kernel_str_bytes` instead"
  251. )]
  252. #[inline]
  253. pub unsafe fn bpf_probe_read_str(src: *const u8, dest: &mut [u8]) -> Result<usize, c_long> {
  254. let len = generated::bpf_probe_read_str(
  255. dest.as_mut_ptr() as *mut c_void,
  256. dest.len() as u32,
  257. src as *const c_void,
  258. );
  259. let len = usize::try_from(len).map_err(|core::num::TryFromIntError { .. }| -1)?;
  260. // this can never happen, it's needed to tell the verifier that len is bounded.
  261. Ok(len.min(dest.len()))
  262. }
  263. /// Read a null-terminated string from _user space_ stored at `src` into `dest`.
  264. ///
  265. /// In case the length of `dest` is smaller then the length of `src`, the read bytes will
  266. /// be truncated to the size of `dest`.
  267. ///
  268. /// # Examples
  269. ///
  270. /// ```no_run
  271. /// # #![expect(dead_code)]
  272. /// # use aya_ebpf::{cty::c_long, helpers::bpf_probe_read_user_str};
  273. /// # fn try_test() -> Result<(), c_long> {
  274. /// # let user_ptr: *const u8 = 0 as _;
  275. /// let mut my_str = [0u8; 16];
  276. /// let num_read = unsafe { bpf_probe_read_user_str(user_ptr, &mut my_str)? };
  277. ///
  278. /// // Do something with num_read and my_str
  279. /// # Ok::<(), c_long>(())
  280. /// # }
  281. /// ```
  282. ///
  283. /// # Errors
  284. ///
  285. /// On failure, this function returns Err(-1).
  286. #[deprecated(note = "Use `bpf_probe_read_user_str_bytes` instead")]
  287. #[inline]
  288. pub unsafe fn bpf_probe_read_user_str(src: *const u8, dest: &mut [u8]) -> Result<usize, c_long> {
  289. let len = generated::bpf_probe_read_user_str(
  290. dest.as_mut_ptr() as *mut c_void,
  291. dest.len() as u32,
  292. src as *const c_void,
  293. );
  294. let len = usize::try_from(len).map_err(|core::num::TryFromIntError { .. }| -1)?;
  295. // this can never happen, it's needed to tell the verifier that len is bounded.
  296. Ok(len.min(dest.len()))
  297. }
  298. /// Returns a byte slice read from _user space_ address `src`.
  299. ///
  300. /// Reads at most `dest.len()` bytes from the `src` address, truncating if the
  301. /// length of the source string is larger than `dest`. On success, the
  302. /// destination buffer is always null terminated, and the returned slice
  303. /// includes the bytes up to and not including NULL.
  304. ///
  305. /// # Examples
  306. ///
  307. /// With an array allocated on the stack (not recommended for bigger strings,
  308. /// eBPF stack limit is 512 bytes):
  309. ///
  310. /// ```no_run
  311. /// # #![expect(dead_code)]
  312. /// # use aya_ebpf::{cty::c_long, helpers::bpf_probe_read_user_str_bytes};
  313. /// # fn try_test() -> Result<(), c_long> {
  314. /// # let user_ptr: *const u8 = 0 as _;
  315. /// let mut buf = [0u8; 16];
  316. /// let my_str_bytes = unsafe { bpf_probe_read_user_str_bytes(user_ptr, &mut buf)? };
  317. ///
  318. /// // Do something with my_str_bytes
  319. /// # Ok::<(), c_long>(())
  320. /// # }
  321. /// ```
  322. ///
  323. /// With a `PerCpuArray` (with size defined by us):
  324. ///
  325. /// ```no_run
  326. /// # use aya_ebpf::{cty::c_long, helpers::bpf_probe_read_user_str_bytes};
  327. /// use aya_ebpf::{macros::map, maps::PerCpuArray};
  328. ///
  329. /// #[repr(C)]
  330. /// pub struct Buf {
  331. /// pub buf: [u8; 4096],
  332. /// }
  333. ///
  334. /// #[map]
  335. /// pub static BUF: PerCpuArray<Buf> = PerCpuArray::with_max_entries(1, 0);
  336. ///
  337. /// # fn try_test() -> Result<(), c_long> {
  338. /// # let user_ptr: *const u8 = 0 as _;
  339. /// let buf = unsafe {
  340. /// let ptr = BUF.get_ptr_mut(0).ok_or(0)?;
  341. /// &mut *ptr
  342. /// };
  343. /// let my_str_bytes = unsafe { bpf_probe_read_user_str_bytes(user_ptr, &mut buf.buf)? };
  344. ///
  345. /// // Do something with my_str_bytes
  346. /// # Ok::<(), c_long>(())
  347. /// # }
  348. /// ```
  349. ///
  350. /// You can also convert the resulted bytes slice into `&str` using
  351. /// [core::str::from_utf8_unchecked]:
  352. ///
  353. /// ```no_run
  354. /// # use aya_ebpf::{cty::c_long, helpers::bpf_probe_read_user_str_bytes};
  355. /// # use aya_ebpf::{macros::map, maps::PerCpuArray};
  356. /// # #[repr(C)]
  357. /// # pub struct Buf {
  358. /// # pub buf: [u8; 4096],
  359. /// # }
  360. /// # #[map]
  361. /// # pub static BUF: PerCpuArray<Buf> = PerCpuArray::with_max_entries(1, 0);
  362. /// # fn try_test() -> Result<(), c_long> {
  363. /// # let user_ptr: *const u8 = 0 as _;
  364. /// # let buf = unsafe {
  365. /// # let ptr = BUF.get_ptr_mut(0).ok_or(0)?;
  366. /// # &mut *ptr
  367. /// # };
  368. /// let my_str = unsafe {
  369. /// core::str::from_utf8_unchecked(bpf_probe_read_user_str_bytes(user_ptr, &mut buf.buf)?)
  370. /// };
  371. ///
  372. /// // Do something with my_str
  373. /// # Ok::<(), c_long>(())
  374. /// # }
  375. /// ```
  376. ///
  377. /// # Errors
  378. ///
  379. /// On failure, this function returns Err(-1).
  380. #[inline]
  381. pub unsafe fn bpf_probe_read_user_str_bytes(
  382. src: *const u8,
  383. dest: &mut [u8],
  384. ) -> Result<&[u8], c_long> {
  385. let len = generated::bpf_probe_read_user_str(
  386. dest.as_mut_ptr() as *mut c_void,
  387. dest.len() as u32,
  388. src as *const c_void,
  389. );
  390. read_str_bytes(len, dest)
  391. }
  392. fn read_str_bytes(len: i64, dest: &[u8]) -> Result<&[u8], c_long> {
  393. // The lower bound is 0, since it's what is returned for b"\0". See the
  394. // bpf_probe_read_user_[user|kernel]_bytes_empty integration tests. The upper bound
  395. // check is not needed since the helper truncates, but the verifier doesn't
  396. // know that so we show it the upper bound.
  397. if !check_bounds_signed(len, 0, dest.len() as i64) {
  398. return Err(-1);
  399. }
  400. // len includes the NULL terminator but not for b"\0" for which the kernel
  401. // returns len=0. So we do a saturating sub and for b"\0" we return the
  402. // empty slice, for all other cases we omit the terminator.
  403. let len = usize::try_from(len).map_err(|core::num::TryFromIntError { .. }| -1)?;
  404. let len = len.saturating_sub(1);
  405. dest.get(..len).ok_or(-1)
  406. }
  407. /// Read a null-terminated string from _kernel space_ stored at `src` into `dest`.
  408. ///
  409. /// In case the length of `dest` is smaller then the length of `src`, the read bytes will
  410. /// be truncated to the size of `dest`.
  411. ///
  412. /// # Examples
  413. ///
  414. /// ```no_run
  415. /// # #![expect(dead_code)]
  416. /// # use aya_ebpf::{cty::c_long, helpers::bpf_probe_read_kernel_str};
  417. /// # fn try_test() -> Result<(), c_long> {
  418. /// # let kernel_ptr: *const u8 = 0 as _;
  419. /// let mut my_str = [0u8; 16];
  420. /// let num_read = unsafe { bpf_probe_read_kernel_str(kernel_ptr, &mut my_str)? };
  421. ///
  422. /// // Do something with num_read and my_str
  423. /// # Ok::<(), c_long>(())
  424. /// # }
  425. /// ```
  426. ///
  427. /// # Errors
  428. ///
  429. /// On failure, this function returns Err(-1).
  430. #[deprecated(note = "Use bpf_probe_read_kernel_str_bytes instead")]
  431. #[inline]
  432. pub unsafe fn bpf_probe_read_kernel_str(src: *const u8, dest: &mut [u8]) -> Result<usize, c_long> {
  433. let len = generated::bpf_probe_read_kernel_str(
  434. dest.as_mut_ptr() as *mut c_void,
  435. dest.len() as u32,
  436. src as *const c_void,
  437. );
  438. let len = usize::try_from(len).map_err(|core::num::TryFromIntError { .. }| -1)?;
  439. // this can never happen, it's needed to tell the verifier that len is bounded.
  440. Ok(len.min(dest.len()))
  441. }
  442. /// Returns a byte slice read from _kernel space_ address `src`.
  443. ///
  444. /// Reads at most `dest.len()` bytes from the `src` address, truncating if the
  445. /// length of the source string is larger than `dest`. On success, the
  446. /// destination buffer is always null terminated, and the returned slice
  447. /// includes the bytes up to and not including NULL.
  448. ///
  449. /// # Examples
  450. ///
  451. /// With an array allocated on the stack (not recommended for bigger strings,
  452. /// eBPF stack limit is 512 bytes):
  453. ///
  454. /// ```no_run
  455. /// # #![expect(dead_code)]
  456. /// # use aya_ebpf::{cty::c_long, helpers::bpf_probe_read_kernel_str_bytes};
  457. /// # fn try_test() -> Result<(), c_long> {
  458. /// # let kernel_ptr: *const u8 = 0 as _;
  459. /// let mut buf = [0u8; 16];
  460. /// let my_str_bytes = unsafe { bpf_probe_read_kernel_str_bytes(kernel_ptr, &mut buf)? };
  461. ///
  462. /// // Do something with my_str_bytes
  463. /// # Ok::<(), c_long>(())
  464. /// # }
  465. /// ```
  466. ///
  467. /// With a `PerCpuArray` (with size defined by us):
  468. ///
  469. /// ```no_run
  470. /// # use aya_ebpf::{cty::c_long, helpers::bpf_probe_read_kernel_str_bytes};
  471. /// use aya_ebpf::{macros::map, maps::PerCpuArray};
  472. ///
  473. /// #[repr(C)]
  474. /// pub struct Buf {
  475. /// pub buf: [u8; 4096],
  476. /// }
  477. ///
  478. /// #[map]
  479. /// pub static BUF: PerCpuArray<Buf> = PerCpuArray::with_max_entries(1, 0);
  480. ///
  481. /// # fn try_test() -> Result<(), c_long> {
  482. /// # let kernel_ptr: *const u8 = 0 as _;
  483. /// let buf = unsafe {
  484. /// let ptr = BUF.get_ptr_mut(0).ok_or(0)?;
  485. /// &mut *ptr
  486. /// };
  487. /// let my_str_bytes = unsafe { bpf_probe_read_kernel_str_bytes(kernel_ptr, &mut buf.buf)? };
  488. ///
  489. /// // Do something with my_str_bytes
  490. /// # Ok::<(), c_long>(())
  491. /// # }
  492. /// ```
  493. ///
  494. /// You can also convert the resulted bytes slice into `&str` using
  495. /// [core::str::from_utf8_unchecked]:
  496. ///
  497. /// ```no_run
  498. /// # use aya_ebpf::{cty::c_long, helpers::bpf_probe_read_kernel_str_bytes};
  499. /// # use aya_ebpf::{macros::map, maps::PerCpuArray};
  500. /// # #[repr(C)]
  501. /// # pub struct Buf {
  502. /// # pub buf: [u8; 4096],
  503. /// # }
  504. /// # #[map]
  505. /// # pub static BUF: PerCpuArray<Buf> = PerCpuArray::with_max_entries(1, 0);
  506. /// # fn try_test() -> Result<(), c_long> {
  507. /// # let kernel_ptr: *const u8 = 0 as _;
  508. /// # let buf = unsafe {
  509. /// # let ptr = BUF.get_ptr_mut(0).ok_or(0)?;
  510. /// # &mut *ptr
  511. /// # };
  512. /// let my_str = unsafe {
  513. /// core::str::from_utf8_unchecked(bpf_probe_read_kernel_str_bytes(kernel_ptr, &mut buf.buf)?)
  514. /// };
  515. ///
  516. /// // Do something with my_str
  517. /// # Ok::<(), c_long>(())
  518. /// # }
  519. /// ```
  520. ///
  521. /// # Errors
  522. ///
  523. /// On failure, this function returns Err(-1).
  524. #[inline]
  525. pub unsafe fn bpf_probe_read_kernel_str_bytes(
  526. src: *const u8,
  527. dest: &mut [u8],
  528. ) -> Result<&[u8], c_long> {
  529. let len = generated::bpf_probe_read_kernel_str(
  530. dest.as_mut_ptr() as *mut c_void,
  531. dest.len() as u32,
  532. src as *const c_void,
  533. );
  534. read_str_bytes(len, dest)
  535. }
  536. /// Write bytes to the _user space_ pointer `src` and store them as a `T`.
  537. ///
  538. /// # Examples
  539. ///
  540. /// ```no_run
  541. /// # #![expect(dead_code)]
  542. /// # use aya_ebpf::{
  543. /// # cty::{c_int, c_long},
  544. /// # helpers::bpf_probe_write_user,
  545. /// # programs::ProbeContext,
  546. /// # };
  547. /// fn try_test(ctx: ProbeContext) -> Result<(), c_long> {
  548. /// let retp: *mut c_int = ctx.arg(0).ok_or(1)?;
  549. /// let val: i32 = 1;
  550. /// // Write the value to the userspace pointer.
  551. /// unsafe { bpf_probe_write_user(retp, &val as *const i32)? };
  552. ///
  553. /// Ok::<(), c_long>(())
  554. /// }
  555. /// ```
  556. ///
  557. /// # Errors
  558. ///
  559. /// On failure, this function returns a negative value wrapped in an `Err`.
  560. #[inline]
  561. pub unsafe fn bpf_probe_write_user<T>(dst: *mut T, src: *const T) -> Result<(), c_long> {
  562. let ret = generated::bpf_probe_write_user(
  563. dst as *mut c_void,
  564. src as *const c_void,
  565. mem::size_of::<T>() as u32,
  566. );
  567. if ret == 0 { Ok(()) } else { Err(ret) }
  568. }
  569. /// Read the `comm` field associated with the current task struct
  570. /// as a `[u8; 16]`.
  571. ///
  572. /// # Examples
  573. ///
  574. /// ```no_run
  575. /// # #![expect(dead_code)]
  576. /// # use aya_ebpf::helpers::bpf_get_current_comm;
  577. /// let comm = bpf_get_current_comm();
  578. ///
  579. /// // Do something with comm
  580. /// ```
  581. ///
  582. /// # Errors
  583. ///
  584. /// On failure, this function returns a negative value wrapped in an `Err`.
  585. #[inline]
  586. pub fn bpf_get_current_comm() -> Result<[u8; 16], c_long> {
  587. let mut comm: [u8; 16usize] = [0; 16];
  588. let ret = unsafe { generated::bpf_get_current_comm(&mut comm as *mut _ as *mut c_void, 16u32) };
  589. if ret == 0 { Ok(comm) } else { Err(ret) }
  590. }
  591. /// Read the process id and thread group id associated with the current task struct as
  592. /// a `u64`.
  593. ///
  594. /// In the return value, the upper 32 bits are the `tgid`, and the lower 32 bits are the
  595. /// `pid`. That is, the returned value is equal to: `(tgid << 32) | pid`. A caller may
  596. /// access the individual fields by either casting to a `u32` or performing a `>> 32` bit
  597. /// shift and casting to a `u32`.
  598. ///
  599. /// Note that the naming conventions used in the kernel differ from user space. From the
  600. /// perspective of user space, `pid` may be thought of as the thread id, and `tgid` may be
  601. /// thought of as the process id. For single-threaded processes, these values are
  602. /// typically the same.
  603. ///
  604. /// # Examples
  605. ///
  606. /// ```no_run
  607. /// # #![expect(dead_code)]
  608. /// # use aya_ebpf::helpers::bpf_get_current_pid_tgid;
  609. /// let tgid = (bpf_get_current_pid_tgid() >> 32) as u32;
  610. /// let pid = bpf_get_current_pid_tgid() as u32;
  611. ///
  612. /// // Do something with pid and tgid
  613. /// ```
  614. #[inline]
  615. pub fn bpf_get_current_pid_tgid() -> u64 {
  616. unsafe { generated::bpf_get_current_pid_tgid() }
  617. }
  618. /// Read the user id and group id associated with the current task struct as
  619. /// a `u64`.
  620. ///
  621. /// In the return value, the upper 32 bits are the `gid`, and the lower 32 bits are the
  622. /// `uid`. That is, the returned value is equal to: `(gid << 32) | uid`. A caller may
  623. /// access the individual fields by either casting to a `u32` or performing a `>> 32` bit
  624. /// shift and casting to a `u32`.
  625. ///
  626. /// # Examples
  627. ///
  628. /// ```no_run
  629. /// # #![expect(dead_code)]
  630. /// # use aya_ebpf::helpers::bpf_get_current_uid_gid;
  631. /// let gid = (bpf_get_current_uid_gid() >> 32) as u32;
  632. /// let uid = bpf_get_current_uid_gid() as u32;
  633. ///
  634. /// // Do something with uid and gid
  635. /// ```
  636. #[inline]
  637. pub fn bpf_get_current_uid_gid() -> u64 {
  638. unsafe { generated::bpf_get_current_uid_gid() }
  639. }
  640. /// Prints a debug message to the BPF debugging pipe.
  641. ///
  642. /// The [format string syntax][fmt] is the same as that of the `printk` kernel
  643. /// function. It is passed in as a fixed-size byte array (`&[u8; N]`), so you
  644. /// will have to prefix your string literal with a `b`. A terminating zero byte
  645. /// is appended automatically.
  646. ///
  647. /// The macro can read from arbitrary pointers, so it must be used in an `unsafe`
  648. /// scope in order to compile.
  649. ///
  650. /// Invocations with less than 4 arguments call the `bpf_trace_printk` helper,
  651. /// otherwise the `bpf_trace_vprintk` function is called. The latter function
  652. /// requires a kernel version >= 5.16 whereas the former has been around since
  653. /// the dawn of eBPF. The return value of the BPF helper is also returned from
  654. /// this macro.
  655. ///
  656. /// Messages can be read by executing the following command in a second terminal:
  657. ///
  658. /// ```bash
  659. /// sudo cat /sys/kernel/debug/tracing/trace_pipe
  660. /// ```
  661. ///
  662. /// If no messages are printed when calling [`bpf_printk!`] after executing the
  663. /// above command, it is possible that tracing must first be enabled by running:
  664. ///
  665. /// ```bash
  666. /// echo 1 | sudo tee /sys/kernel/debug/tracing/tracing_on
  667. /// ```
  668. ///
  669. /// # Example
  670. ///
  671. /// ```no_run
  672. /// # use aya_ebpf::helpers::bpf_printk;
  673. /// unsafe {
  674. /// bpf_printk!(b"hi there! dec: %d, hex: 0x%08X", 42, 0x1234);
  675. /// }
  676. /// ```
  677. ///
  678. /// [fmt]: https://www.kernel.org/doc/html/latest/core-api/printk-formats.html#printk-specifiers
  679. #[macro_export]
  680. macro_rules! bpf_printk {
  681. ($fmt:literal $(,)? $($arg:expr),* $(,)?) => {{
  682. use $crate::helpers::PrintkArg;
  683. const FMT: [u8; { $fmt.len() + 1 }] = $crate::helpers::zero_pad_array::<
  684. { $fmt.len() }, { $fmt.len() + 1 }>(*$fmt);
  685. let data = [$(PrintkArg::from($arg)),*];
  686. $crate::helpers::bpf_printk_impl(&FMT, &data)
  687. }};
  688. }
  689. // Macros are always exported from the crate root. Also export it from `helpers`.
  690. #[doc(inline)]
  691. pub use bpf_printk;
  692. /// Argument ready to be passed to `printk` BPF helper.
  693. #[repr(transparent)]
  694. #[derive(Copy, Clone)]
  695. pub struct PrintkArg([u8; 8]);
  696. impl PrintkArg {
  697. /// Manually construct a `printk` BPF helper argument.
  698. #[inline]
  699. pub fn from_raw(x: u64) -> Self {
  700. Self(x.to_ne_bytes())
  701. }
  702. }
  703. macro_rules! impl_integer_promotion {
  704. ($($ty:ty : via $via:ty),* $(,)?) => {$(
  705. /// Create `printk` arguments from integer types.
  706. impl From<$ty> for PrintkArg {
  707. #[inline]
  708. fn from(x: $ty) -> PrintkArg {
  709. PrintkArg((x as $via).to_ne_bytes())
  710. }
  711. }
  712. )*}
  713. }
  714. impl_integer_promotion!(
  715. char: via usize,
  716. u8: via usize,
  717. u16: via usize,
  718. u32: via usize,
  719. u64: via usize,
  720. usize: via usize,
  721. i8: via isize,
  722. i16: via isize,
  723. i32: via isize,
  724. i64: via isize,
  725. isize: via isize,
  726. );
  727. /// Construct `printk` BPF helper arguments from constant pointers.
  728. impl<T> From<*const T> for PrintkArg {
  729. #[inline]
  730. fn from(x: *const T) -> Self {
  731. PrintkArg((x as usize).to_ne_bytes())
  732. }
  733. }
  734. /// Construct `printk` BPF helper arguments from mutable pointers.
  735. impl<T> From<*mut T> for PrintkArg {
  736. #[inline]
  737. fn from(x: *mut T) -> Self {
  738. PrintkArg((x as usize).to_ne_bytes())
  739. }
  740. }
  741. /// Expands the given byte array to `DST_LEN`, right-padding it with zeros. If
  742. /// `DST_LEN` is smaller than `SRC_LEN`, the array is instead truncated.
  743. ///
  744. /// This function serves as a helper for the [`bpf_printk!`] macro.
  745. #[doc(hidden)]
  746. pub const fn zero_pad_array<const SRC_LEN: usize, const DST_LEN: usize>(
  747. src: [u8; SRC_LEN],
  748. ) -> [u8; DST_LEN] {
  749. let mut out: [u8; DST_LEN] = [0u8; DST_LEN];
  750. // The `min` function is not `const`. Hand-roll it.
  751. let mut i = if DST_LEN > SRC_LEN { SRC_LEN } else { DST_LEN };
  752. while i > 0 {
  753. i -= 1;
  754. out[i] = src[i];
  755. }
  756. out
  757. }
  758. /// Internal helper function for the [`bpf_printk!`] macro.
  759. ///
  760. /// The BPF helpers require the length for both the format string as well as
  761. /// the argument array to be of constant size to pass the verifier. Const
  762. /// generics are used to represent this requirement in Rust.
  763. #[inline]
  764. #[doc(hidden)]
  765. pub unsafe fn bpf_printk_impl<const FMT_LEN: usize, const NUM_ARGS: usize>(
  766. fmt: &[u8; FMT_LEN],
  767. args: &[PrintkArg; NUM_ARGS],
  768. ) -> i64 {
  769. // This function can't be wrapped in `helpers.rs` because it has variadic
  770. // arguments. We also can't turn the definitions in `helpers.rs` into
  771. // `const`s because MIRI believes casting arbitrary integers to function
  772. // pointers to be an error.
  773. let printk: unsafe extern "C" fn(fmt: *const c_char, fmt_size: u32, ...) -> c_long =
  774. mem::transmute(6usize);
  775. let fmt_ptr = fmt.as_ptr() as *const c_char;
  776. let fmt_size = fmt.len() as u32;
  777. match NUM_ARGS {
  778. 0 => printk(fmt_ptr, fmt_size),
  779. 1 => printk(fmt_ptr, fmt_size, args[0]),
  780. 2 => printk(fmt_ptr, fmt_size, args[0], args[1]),
  781. 3 => printk(fmt_ptr, fmt_size, args[0], args[1], args[2]),
  782. _ => {
  783. generated::bpf_trace_vprintk(fmt_ptr, fmt_size, args.as_ptr() as _, (NUM_ARGS * 8) as _)
  784. }
  785. }
  786. }
  787. /// Compares the given byte `s1` with a [`&CStr`](core::ffi::CStr) `s2`.
  788. ///
  789. /// # Examples
  790. ///
  791. /// ```no_run
  792. /// # use aya_ebpf::helpers::bpf_strncmp;
  793. /// # let data = b"something";
  794. /// assert_ne!(bpf_strncmp(data, c"foo"), core::cmp::Ordering::Equal);
  795. /// ```
  796. #[inline]
  797. pub fn bpf_strncmp<const N: usize>(s1: &[u8; N], s2: &CStr) -> Ordering {
  798. // NB: s1 does not need to be null-terminated.
  799. //
  800. // See https://github.com/torvalds/linux/blob/adc218676/include/uapi/linux/bpf.h#L5391-L5393.
  801. //
  802. // NB: s1's size must be known at compile time to appease the verifier. This is also the typical
  803. // usage of strncmp in C programs.
  804. unsafe { generated::bpf_strncmp(s1.as_ptr() as *const _, N as u32, s2.as_ptr() as *const _) }
  805. .cmp(&0)
  806. }