helpers.rs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703
  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::cty::{c_char, c_long, c_void};
  14. /// Read bytes stored at `src` and store them as a `T`.
  15. ///
  16. /// Generally speaking, the more specific [`bpf_probe_read_user`] and
  17. /// [`bpf_probe_read_kernel`] should be preferred over this function.
  18. ///
  19. /// Returns a bitwise copy of `mem::size_of::<T>()` bytes stored at the user space address
  20. /// `src`. See `bpf_probe_read_kernel` for reading kernel space memory.
  21. ///
  22. /// # Examples
  23. ///
  24. /// ```no_run
  25. /// # #![allow(dead_code)]
  26. /// # use aya_bpf::{cty::{c_int, c_long}, helpers::bpf_probe_read};
  27. /// # fn try_test() -> Result<(), c_long> {
  28. /// # let kernel_ptr: *const c_int = 0 as _;
  29. /// let my_int: c_int = unsafe { bpf_probe_read(kernel_ptr)? };
  30. ///
  31. /// // Do something with my_int
  32. /// # Ok::<(), c_long>(())
  33. /// # }
  34. /// ```
  35. ///
  36. /// # Errors
  37. ///
  38. /// On failure, this function returns a negative value wrapped in an `Err`.
  39. #[inline]
  40. pub unsafe fn bpf_probe_read<T>(src: *const T) -> Result<T, c_long> {
  41. let mut v: MaybeUninit<T> = MaybeUninit::uninit();
  42. let ret = gen::bpf_probe_read(
  43. v.as_mut_ptr() as *mut c_void,
  44. mem::size_of::<T>() as u32,
  45. src as *const c_void,
  46. );
  47. if ret == 0 {
  48. Ok(v.assume_init())
  49. } else {
  50. Err(ret)
  51. }
  52. }
  53. /// Read bytes from the pointer `src` into the provided destination buffer.
  54. ///
  55. /// Generally speaking, the more specific [`bpf_probe_read_user_buf`] and
  56. /// [`bpf_probe_read_kernel_buf`] should be preferred over this function.
  57. ///
  58. /// # Examples
  59. ///
  60. /// ```no_run
  61. /// # #![allow(dead_code)]
  62. /// # use aya_bpf::{cty::{c_int, c_long}, helpers::bpf_probe_read_buf};
  63. /// # fn try_test() -> Result<(), c_long> {
  64. /// # let ptr: *const u8 = 0 as _;
  65. /// let mut buf = [0u8; 16];
  66. /// unsafe { bpf_probe_read_buf(ptr, &mut buf)? };
  67. ///
  68. /// # Ok::<(), c_long>(())
  69. /// # }
  70. /// ```
  71. ///
  72. /// # Errors
  73. ///
  74. /// On failure, this function returns a negative value wrapped in an `Err`.
  75. #[inline]
  76. pub unsafe fn bpf_probe_read_buf(src: *const u8, dst: &mut [u8]) -> Result<(), c_long> {
  77. let ret = gen::bpf_probe_read(
  78. dst.as_mut_ptr() as *mut c_void,
  79. dst.len() as u32,
  80. src as *const c_void,
  81. );
  82. if ret == 0 {
  83. Ok(())
  84. } else {
  85. Err(ret)
  86. }
  87. }
  88. /// Read bytes stored at the _user space_ pointer `src` and store them as a `T`.
  89. ///
  90. /// Returns a bitwise copy of `mem::size_of::<T>()` bytes stored at the user space address
  91. /// `src`. See `bpf_probe_read_kernel` for reading kernel space memory.
  92. ///
  93. /// # Examples
  94. ///
  95. /// ```no_run
  96. /// # #![allow(dead_code)]
  97. /// # use aya_bpf::{cty::{c_int, c_long}, helpers::bpf_probe_read_user};
  98. /// # fn try_test() -> Result<(), c_long> {
  99. /// # let user_ptr: *const c_int = 0 as _;
  100. /// let my_int: c_int = unsafe { bpf_probe_read_user(user_ptr)? };
  101. ///
  102. /// // Do something with my_int
  103. /// # Ok::<(), c_long>(())
  104. /// # }
  105. /// ```
  106. ///
  107. /// # Errors
  108. ///
  109. /// On failure, this function returns a negative value wrapped in an `Err`.
  110. #[inline]
  111. pub unsafe fn bpf_probe_read_user<T>(src: *const T) -> Result<T, c_long> {
  112. let mut v: MaybeUninit<T> = MaybeUninit::uninit();
  113. let ret = gen::bpf_probe_read_user(
  114. v.as_mut_ptr() as *mut c_void,
  115. mem::size_of::<T>() as u32,
  116. src as *const c_void,
  117. );
  118. if ret == 0 {
  119. Ok(v.assume_init())
  120. } else {
  121. Err(ret)
  122. }
  123. }
  124. /// Read bytes from the _user space_ pointer `src` into the provided destination
  125. /// buffer.
  126. ///
  127. /// # Examples
  128. ///
  129. /// ```no_run
  130. /// # #![allow(dead_code)]
  131. /// # use aya_bpf::{cty::{c_int, c_long}, helpers::bpf_probe_read_user_buf};
  132. /// # fn try_test() -> Result<(), c_long> {
  133. /// # let user_ptr: *const u8 = 0 as _;
  134. /// let mut buf = [0u8; 16];
  135. /// unsafe { bpf_probe_read_user_buf(user_ptr, &mut buf)? };
  136. ///
  137. /// # Ok::<(), c_long>(())
  138. /// # }
  139. /// ```
  140. ///
  141. /// # Errors
  142. ///
  143. /// On failure, this function returns a negative value wrapped in an `Err`.
  144. #[inline]
  145. pub unsafe fn bpf_probe_read_user_buf(src: *const u8, dst: &mut [u8]) -> Result<(), c_long> {
  146. let ret = gen::bpf_probe_read_user(
  147. dst.as_mut_ptr() as *mut c_void,
  148. dst.len() as u32,
  149. src as *const c_void,
  150. );
  151. if ret == 0 {
  152. Ok(())
  153. } else {
  154. Err(ret)
  155. }
  156. }
  157. /// Read bytes stored at the _kernel space_ pointer `src` and store them as a `T`.
  158. ///
  159. /// Returns a bitwise copy of `mem::size_of::<T>()` bytes stored at the kernel space address
  160. /// `src`. See `bpf_probe_read_user` for reading user space memory.
  161. ///
  162. /// # Examples
  163. ///
  164. /// ```no_run
  165. /// # #![allow(dead_code)]
  166. /// # use aya_bpf::{cty::{c_int, c_long}, helpers::bpf_probe_read_kernel};
  167. /// # fn try_test() -> Result<(), c_long> {
  168. /// # let kernel_ptr: *const c_int = 0 as _;
  169. /// let my_int: c_int = unsafe { bpf_probe_read_kernel(kernel_ptr)? };
  170. ///
  171. /// // Do something with my_int
  172. /// # Ok::<(), c_long>(())
  173. /// # }
  174. /// ```
  175. ///
  176. /// # Errors
  177. ///
  178. /// On failure, this function returns a negative value wrapped in an `Err`.
  179. #[inline]
  180. pub unsafe fn bpf_probe_read_kernel<T>(src: *const T) -> Result<T, c_long> {
  181. let mut v: MaybeUninit<T> = MaybeUninit::uninit();
  182. let ret = gen::bpf_probe_read_kernel(
  183. v.as_mut_ptr() as *mut c_void,
  184. mem::size_of::<T>() as u32,
  185. src as *const c_void,
  186. );
  187. if ret == 0 {
  188. Ok(v.assume_init())
  189. } else {
  190. Err(ret)
  191. }
  192. }
  193. /// Read bytes from the _kernel space_ pointer `src` into the provided destination
  194. /// buffer.
  195. ///
  196. /// # Examples
  197. ///
  198. /// ```no_run
  199. /// # #![allow(dead_code)]
  200. /// # use aya_bpf::{cty::{c_int, c_long}, helpers::bpf_probe_read_kernel_buf};
  201. /// # fn try_test() -> Result<(), c_long> {
  202. /// # let kernel_ptr: *const u8 = 0 as _;
  203. /// let mut buf = [0u8; 16];
  204. /// unsafe { bpf_probe_read_kernel_buf(kernel_ptr, &mut buf)? };
  205. ///
  206. /// # Ok::<(), c_long>(())
  207. /// # }
  208. /// ```
  209. ///
  210. /// # Errors
  211. ///
  212. /// On failure, this function returns a negative value wrapped in an `Err`.
  213. #[inline]
  214. pub unsafe fn bpf_probe_read_kernel_buf(src: *const u8, dst: &mut [u8]) -> Result<(), c_long> {
  215. let ret = gen::bpf_probe_read_kernel(
  216. dst.as_mut_ptr() as *mut c_void,
  217. dst.len() as u32,
  218. src as *const c_void,
  219. );
  220. if ret == 0 {
  221. Ok(())
  222. } else {
  223. Err(ret)
  224. }
  225. }
  226. /// Read a null-terminated string stored at `src` into `dest`.
  227. ///
  228. /// Generally speaking, the more specific [`bpf_probe_read_user_str`] and
  229. /// [`bpf_probe_read_kernel_str`] should be preferred over this function.
  230. ///
  231. /// In case the length of `dest` is smaller then the length of `src`, the read bytes will
  232. /// be truncated to the size of `dest`.
  233. ///
  234. /// # Examples
  235. ///
  236. /// ```no_run
  237. /// # #![allow(dead_code)]
  238. /// # use aya_bpf::{cty::c_long, helpers::bpf_probe_read_str};
  239. /// # fn try_test() -> Result<(), c_long> {
  240. /// # let kernel_ptr: *const u8 = 0 as _;
  241. /// let mut my_str = [0u8; 16];
  242. /// let num_read = unsafe { bpf_probe_read_str(kernel_ptr, &mut my_str)? };
  243. ///
  244. /// // Do something with num_read and my_str
  245. /// # Ok::<(), c_long>(())
  246. /// # }
  247. /// ```
  248. ///
  249. /// # Errors
  250. ///
  251. /// On failure, this function returns Err(-1).
  252. #[deprecated(
  253. note = "Use `bpf_probe_read_user_str_bytes` or `bpf_probe_read_kernel_str_bytes` instead"
  254. )]
  255. #[inline]
  256. pub unsafe fn bpf_probe_read_str(src: *const u8, dest: &mut [u8]) -> Result<usize, c_long> {
  257. let len = gen::bpf_probe_read_str(
  258. dest.as_mut_ptr() as *mut c_void,
  259. dest.len() as u32,
  260. src as *const c_void,
  261. );
  262. if len < 0 {
  263. return Err(-1);
  264. }
  265. let mut len = len as usize;
  266. if len > dest.len() {
  267. // this can never happen, it's needed to tell the verifier that len is
  268. // bounded
  269. len = dest.len();
  270. }
  271. Ok(len as usize)
  272. }
  273. /// Read a null-terminated string from _user space_ stored at `src` into `dest`.
  274. ///
  275. /// In case the length of `dest` is smaller then the length of `src`, the read bytes will
  276. /// be truncated to the size of `dest`.
  277. ///
  278. /// # Examples
  279. ///
  280. /// ```no_run
  281. /// # #![allow(dead_code)]
  282. /// # use aya_bpf::{cty::c_long, helpers::bpf_probe_read_user_str};
  283. /// # fn try_test() -> Result<(), c_long> {
  284. /// # let user_ptr: *const u8 = 0 as _;
  285. /// let mut my_str = [0u8; 16];
  286. /// let num_read = unsafe { bpf_probe_read_user_str(user_ptr, &mut my_str)? };
  287. ///
  288. /// // Do something with num_read and my_str
  289. /// # Ok::<(), c_long>(())
  290. /// # }
  291. /// ```
  292. ///
  293. /// # Errors
  294. ///
  295. /// On failure, this function returns Err(-1).
  296. #[deprecated(note = "Use `bpf_probe_read_user_str_bytes` instead")]
  297. #[inline]
  298. pub unsafe fn bpf_probe_read_user_str(src: *const u8, dest: &mut [u8]) -> Result<usize, c_long> {
  299. let len = gen::bpf_probe_read_user_str(
  300. dest.as_mut_ptr() as *mut c_void,
  301. dest.len() as u32,
  302. src as *const c_void,
  303. );
  304. if len < 0 {
  305. return Err(-1);
  306. }
  307. let mut len = len as usize;
  308. if len > dest.len() {
  309. // this can never happen, it's needed to tell the verifier that len is
  310. // bounded
  311. len = dest.len();
  312. }
  313. Ok(len as usize)
  314. }
  315. /// Returns a byte slice read from _user space_ address `src`.
  316. ///
  317. /// Reads at most `dest.len()` bytes from the `src` address, truncating if the
  318. /// length of the source string is larger than `dest`. On success, the
  319. /// destination buffer is always null terminated, and the returned slice
  320. /// includes the bytes up to and not including NULL.
  321. ///
  322. /// # Examples
  323. ///
  324. /// With an array allocated on the stack (not recommended for bigger strings,
  325. /// eBPF stack limit is 512 bytes):
  326. ///
  327. /// ```no_run
  328. /// # #![allow(dead_code)]
  329. /// # use aya_bpf::{cty::c_long, helpers::bpf_probe_read_user_str_bytes};
  330. /// # fn try_test() -> Result<(), c_long> {
  331. /// # let user_ptr: *const u8 = 0 as _;
  332. /// let mut buf = [0u8; 16];
  333. /// let my_str_bytes = unsafe { bpf_probe_read_user_str_bytes(user_ptr, &mut buf)? };
  334. ///
  335. /// // Do something with my_str_bytes
  336. /// # Ok::<(), c_long>(())
  337. /// # }
  338. /// ```
  339. ///
  340. /// With a `PerCpuArray` (with size defined by us):
  341. ///
  342. /// ```no_run
  343. /// # use aya_bpf::{cty::c_long, helpers::bpf_probe_read_user_str_bytes};
  344. /// use aya_bpf::{macros::map, maps::PerCpuArray};
  345. ///
  346. /// #[repr(C)]
  347. /// pub struct Buf {
  348. /// pub buf: [u8; 4096],
  349. /// }
  350. ///
  351. /// #[map]
  352. /// pub static mut BUF: PerCpuArray<Buf> = PerCpuArray::with_max_entries(1, 0);
  353. ///
  354. /// # fn try_test() -> Result<(), c_long> {
  355. /// # let user_ptr: *const u8 = 0 as _;
  356. /// let buf = unsafe {
  357. /// let ptr = BUF.get_ptr_mut(0).ok_or(0)?;
  358. /// &mut *ptr
  359. /// };
  360. /// let my_str_bytes = unsafe { bpf_probe_read_user_str_bytes(user_ptr, &mut buf.buf)? };
  361. ///
  362. /// // Do something with my_str_bytes
  363. /// # Ok::<(), c_long>(())
  364. /// # }
  365. /// ```
  366. ///
  367. /// You can also convert the resulted bytes slice into `&str` using
  368. /// [core::str::from_utf8_unchecked]:
  369. ///
  370. /// ```no_run
  371. /// # #![allow(dead_code)]
  372. /// # use aya_bpf::{cty::c_long, helpers::bpf_probe_read_user_str_bytes};
  373. /// # use aya_bpf::{macros::map, maps::PerCpuArray};
  374. /// # #[repr(C)]
  375. /// # pub struct Buf {
  376. /// # pub buf: [u8; 4096],
  377. /// # }
  378. /// # #[map]
  379. /// # pub static mut BUF: PerCpuArray<Buf> = PerCpuArray::with_max_entries(1, 0);
  380. /// # fn try_test() -> Result<(), c_long> {
  381. /// # let user_ptr: *const u8 = 0 as _;
  382. /// # let buf = unsafe {
  383. /// # let ptr = BUF.get_ptr_mut(0).ok_or(0)?;
  384. /// # &mut *ptr
  385. /// # };
  386. /// let my_str = unsafe {
  387. /// core::str::from_utf8_unchecked(bpf_probe_read_user_str_bytes(user_ptr, &mut buf.buf)?)
  388. /// };
  389. ///
  390. /// // Do something with my_str
  391. /// # Ok::<(), c_long>(())
  392. /// # }
  393. /// ```
  394. ///
  395. /// # Errors
  396. ///
  397. /// On failure, this function returns Err(-1).
  398. #[inline]
  399. pub unsafe fn bpf_probe_read_user_str_bytes(
  400. src: *const u8,
  401. dest: &mut [u8],
  402. ) -> Result<&[u8], c_long> {
  403. let len = gen::bpf_probe_read_user_str(
  404. dest.as_mut_ptr() as *mut c_void,
  405. dest.len() as u32,
  406. src as *const c_void,
  407. );
  408. if len < 0 {
  409. return Err(-1);
  410. }
  411. let len = len as usize;
  412. if len >= dest.len() {
  413. // this can never happen, it's needed to tell the verifier that len is
  414. // bounded
  415. return Err(-1);
  416. }
  417. Ok(&dest[..len])
  418. }
  419. /// Read a null-terminated string from _kernel space_ stored at `src` into `dest`.
  420. ///
  421. /// In case the length of `dest` is smaller then the length of `src`, the read bytes will
  422. /// be truncated to the size of `dest`.
  423. ///
  424. /// # Examples
  425. ///
  426. /// ```no_run
  427. /// # #![allow(dead_code)]
  428. /// # use aya_bpf::{cty::c_long, helpers::bpf_probe_read_kernel_str};
  429. /// # fn try_test() -> Result<(), c_long> {
  430. /// # let kernel_ptr: *const u8 = 0 as _;
  431. /// let mut my_str = [0u8; 16];
  432. /// let num_read = unsafe { bpf_probe_read_kernel_str(kernel_ptr, &mut my_str)? };
  433. ///
  434. /// // Do something with num_read and my_str
  435. /// # Ok::<(), c_long>(())
  436. /// # }
  437. /// ```
  438. ///
  439. /// # Errors
  440. ///
  441. /// On failure, this function returns Err(-1).
  442. #[deprecated(note = "Use bpf_probe_read_kernel_str_bytes instead")]
  443. #[inline]
  444. pub unsafe fn bpf_probe_read_kernel_str(src: *const u8, dest: &mut [u8]) -> Result<usize, c_long> {
  445. let len = gen::bpf_probe_read_kernel_str(
  446. dest.as_mut_ptr() as *mut c_void,
  447. dest.len() as u32,
  448. src as *const c_void,
  449. );
  450. if len < 0 {
  451. return Err(-1);
  452. }
  453. let mut len = len as usize;
  454. if len > dest.len() {
  455. // this can never happen, it's needed to tell the verifier that len is
  456. // bounded
  457. len = dest.len();
  458. }
  459. Ok(len as usize)
  460. }
  461. /// Returns a byte slice read from _kernel space_ address `src`.
  462. ///
  463. /// Reads at most `dest.len()` bytes from the `src` address, truncating if the
  464. /// length of the source string is larger than `dest`. On success, the
  465. /// destination buffer is always null terminated, and the returned slice
  466. /// includes the bytes up to and not including NULL.
  467. ///
  468. /// # Examples
  469. ///
  470. /// With an array allocated on the stack (not recommended for bigger strings,
  471. /// eBPF stack limit is 512 bytes):
  472. ///
  473. /// ```no_run
  474. /// # #![allow(dead_code)]
  475. /// # use aya_bpf::{cty::c_long, helpers::bpf_probe_read_kernel_str_bytes};
  476. /// # fn try_test() -> Result<(), c_long> {
  477. /// # let kernel_ptr: *const u8 = 0 as _;
  478. /// let mut buf = [0u8; 16];
  479. /// let my_str_bytes = unsafe { bpf_probe_read_kernel_str_bytes(kernel_ptr, &mut buf)? };
  480. ///
  481. /// // Do something with my_str_bytes
  482. /// # Ok::<(), c_long>(())
  483. /// # }
  484. /// ```
  485. ///
  486. /// With a `PerCpuArray` (with size defined by us):
  487. ///
  488. /// ```no_run
  489. /// # #![allow(dead_code)]
  490. /// # use aya_bpf::{cty::c_long, helpers::bpf_probe_read_kernel_str_bytes};
  491. /// use aya_bpf::{macros::map, maps::PerCpuArray};
  492. ///
  493. /// #[repr(C)]
  494. /// pub struct Buf {
  495. /// pub buf: [u8; 4096],
  496. /// }
  497. ///
  498. /// #[map]
  499. /// pub static mut BUF: PerCpuArray<Buf> = PerCpuArray::with_max_entries(1, 0);
  500. ///
  501. /// # fn try_test() -> Result<(), c_long> {
  502. /// # let kernel_ptr: *const u8 = 0 as _;
  503. /// let buf = unsafe {
  504. /// let ptr = BUF.get_ptr_mut(0).ok_or(0)?;
  505. /// &mut *ptr
  506. /// };
  507. /// let my_str_bytes = unsafe { bpf_probe_read_kernel_str_bytes(kernel_ptr, &mut buf.buf)? };
  508. ///
  509. /// // Do something with my_str_bytes
  510. /// # Ok::<(), c_long>(())
  511. /// # }
  512. /// ```
  513. ///
  514. /// You can also convert the resulted bytes slice into `&str` using
  515. /// [core::str::from_utf8_unchecked]:
  516. ///
  517. /// ```no_run
  518. /// # #![allow(dead_code)]
  519. /// # use aya_bpf::{cty::c_long, helpers::bpf_probe_read_kernel_str_bytes};
  520. /// # use aya_bpf::{macros::map, maps::PerCpuArray};
  521. /// # #[repr(C)]
  522. /// # pub struct Buf {
  523. /// # pub buf: [u8; 4096],
  524. /// # }
  525. /// # #[map]
  526. /// # pub static mut BUF: PerCpuArray<Buf> = PerCpuArray::with_max_entries(1, 0);
  527. /// # fn try_test() -> Result<(), c_long> {
  528. /// # let kernel_ptr: *const u8 = 0 as _;
  529. /// # let buf = unsafe {
  530. /// # let ptr = BUF.get_ptr_mut(0).ok_or(0)?;
  531. /// # &mut *ptr
  532. /// # };
  533. /// let my_str = unsafe {
  534. /// core::str::from_utf8_unchecked(bpf_probe_read_kernel_str_bytes(kernel_ptr, &mut buf.buf)?)
  535. /// };
  536. ///
  537. /// // Do something with my_str
  538. /// # Ok::<(), c_long>(())
  539. /// # }
  540. /// ```
  541. ///
  542. /// # Errors
  543. ///
  544. /// On failure, this function returns Err(-1).
  545. #[inline]
  546. pub unsafe fn bpf_probe_read_kernel_str_bytes(
  547. src: *const u8,
  548. dest: &mut [u8],
  549. ) -> Result<&[u8], c_long> {
  550. let len = gen::bpf_probe_read_kernel_str(
  551. dest.as_mut_ptr() as *mut c_void,
  552. dest.len() as u32,
  553. src as *const c_void,
  554. );
  555. if len < 0 {
  556. return Err(-1);
  557. }
  558. let len = len as usize;
  559. if len >= dest.len() {
  560. // this can never happen, it's needed to tell the verifier that len is
  561. // bounded
  562. return Err(-1);
  563. }
  564. Ok(&dest[..len])
  565. }
  566. /// Write bytes to the _user space_ pointer `src` and store them as a `T`.
  567. ///
  568. /// # Examples
  569. ///
  570. /// ```no_run
  571. /// # #![allow(dead_code)]
  572. /// # use aya_bpf::{
  573. /// # cty::{c_int, c_long},
  574. /// # helpers::bpf_probe_write_user,
  575. /// # programs::ProbeContext,
  576. /// # };
  577. /// fn try_test(ctx: ProbeContext) -> Result<(), c_long> {
  578. /// let retp: *mut c_int = ctx.arg(0).ok_or(1)?;
  579. /// let val: i32 = 1;
  580. /// // Write the value to the userspace pointer.
  581. /// unsafe { bpf_probe_write_user(retp, &val as *const i32)? };
  582. ///
  583. /// Ok::<(), c_long>(())
  584. /// }
  585. /// ```
  586. ///
  587. /// # Errors
  588. ///
  589. /// On failure, this function returns a negative value wrapped in an `Err`.
  590. #[allow(clippy::fn_to_numeric_cast_with_truncation)]
  591. #[inline]
  592. pub unsafe fn bpf_probe_write_user<T>(dst: *mut T, src: *const T) -> Result<(), c_long> {
  593. let ret = gen::bpf_probe_write_user(
  594. dst as *mut c_void,
  595. src as *const c_void,
  596. mem::size_of::<T>() as u32,
  597. );
  598. if ret == 0 {
  599. Ok(())
  600. } else {
  601. Err(ret)
  602. }
  603. }
  604. /// Read the `comm` field associated with the current task struct
  605. /// as a `[c_char; 16]`.
  606. ///
  607. /// # Examples
  608. ///
  609. /// ```no_run
  610. /// # #![allow(dead_code)]
  611. /// # use aya_bpf::helpers::bpf_get_current_comm;
  612. /// let comm = bpf_get_current_comm();
  613. ///
  614. /// // Do something with comm
  615. /// ```
  616. ///
  617. /// # Errors
  618. ///
  619. /// On failure, this function returns a negative value wrapped in an `Err`.
  620. #[inline]
  621. pub fn bpf_get_current_comm() -> Result<[c_char; 16], c_long> {
  622. let mut comm: [c_char; 16usize] = [0; 16];
  623. let ret = unsafe { gen::bpf_get_current_comm(&mut comm as *mut _ as *mut c_void, 16u32) };
  624. if ret == 0 {
  625. Ok(comm)
  626. } else {
  627. Err(ret)
  628. }
  629. }
  630. /// Read the process id and thread group id associated with the current task struct as
  631. /// a `u64`.
  632. ///
  633. /// In the return value, the upper 32 bits are the `tgid`, and the lower 32 bits are the
  634. /// `pid`. That is, the returned value is equal to: `(tgid << 32) | pid`. A caller may
  635. /// access the individual fields by either casting to a `u32` or performing a `>> 32` bit
  636. /// shift and casting to a `u32`.
  637. ///
  638. /// Note that the naming conventions used in the kernel differ from user space. From the
  639. /// perspective of user space, `pid` may be thought of as the thread id, and `tgid` may be
  640. /// thought of as the process id. For single-threaded processes, these values are
  641. /// typically the same.
  642. ///
  643. /// # Examples
  644. ///
  645. /// ```no_run
  646. /// # #![allow(dead_code)]
  647. /// # use aya_bpf::helpers::bpf_get_current_pid_tgid;
  648. /// let tgid = (bpf_get_current_pid_tgid() >> 32) as u32;
  649. /// let pid = bpf_get_current_pid_tgid() as u32;
  650. ///
  651. /// // Do something with pid and tgid
  652. /// ```
  653. #[inline]
  654. pub fn bpf_get_current_pid_tgid() -> u64 {
  655. unsafe { gen::bpf_get_current_pid_tgid() }
  656. }
  657. /// Read the user id and group id associated with the current task struct as
  658. /// a `u64`.
  659. ///
  660. /// In the return value, the upper 32 bits are the `gid`, and the lower 32 bits are the
  661. /// `uid`. That is, the returned value is equal to: `(gid << 32) | uid`. A caller may
  662. /// access the individual fields by either casting to a `u32` or performing a `>> 32` bit
  663. /// shift and casting to a `u32`.
  664. ///
  665. /// # Examples
  666. ///
  667. /// ```no_run
  668. /// # #![allow(dead_code)]
  669. /// # use aya_bpf::helpers::bpf_get_current_uid_gid;
  670. /// let gid = (bpf_get_current_uid_gid() >> 32) as u32;
  671. /// let uid = bpf_get_current_uid_gid() as u32;
  672. ///
  673. /// // Do something with uid and gid
  674. /// ```
  675. #[inline]
  676. pub fn bpf_get_current_uid_gid() -> u64 {
  677. unsafe { gen::bpf_get_current_uid_gid() }
  678. }