helpers.rs 25 KB

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