diff --git a/aya/src/bpf.rs b/aya/src/bpf.rs index 3e1d4404b..93f58c3e9 100644 --- a/aya/src/bpf.rs +++ b/aya/src/bpf.rs @@ -1117,7 +1117,7 @@ impl Ebpf { /// /// let program: &mut UProbe = bpf.program_mut("SSL_read").unwrap().try_into()?; /// program.load()?; - /// program.attach("SSL_read", "libssl", None, None)?; + /// program.attach("SSL_read", "libssl", None)?; /// # Ok::<(), aya::EbpfError>(()) /// ``` pub fn program_mut(&mut self, name: &str) -> Option<&mut Program> { diff --git a/aya/src/programs/uprobe.rs b/aya/src/programs/uprobe.rs index 0e15fc39f..a0ec8ec12 100644 --- a/aya/src/programs/uprobe.rs +++ b/aya/src/programs/uprobe.rs @@ -72,6 +72,23 @@ impl From for UProbeAttachLocation<'static> { } } +/// Describes a single attachment point along with its optional cookie. +pub struct UProbeAttachPoint<'a> { + /// The actual target location. + pub location: UProbeAttachLocation<'a>, + /// Optional cookie available via `bpf_get_attach_cookie()`. + pub cookie: Option, +} + +impl<'a, L: Into>> From for UProbeAttachPoint<'a> { + fn from(location: L) -> Self { + Self { + location: location.into(), + cookie: None, + } + } +} + impl UProbe { /// The type of the program according to the kernel. pub const PROGRAM_TYPE: ProgramType = ProgramType::KProbe; @@ -90,9 +107,9 @@ impl UProbe { /// Attaches the program. /// /// Attaches the uprobe to the function `fn_name` defined in the `target`. - /// If `offset` is non-zero, it is added to the address of the target - /// function. If `pid` is not `None`, the program executes only when the - /// target function is executed by the given `pid`. + /// If the attach point specifies an offset, it is added to the address of + /// the target function. If `pid` is not `None`, the program executes only + /// when the target function is executed by the given `pid`. /// /// The `target` argument can be an absolute path to a binary or library, or /// a library name (eg: `"libc"`). @@ -104,17 +121,19 @@ impl UProbe { /// The returned value can be used to detach, see [UProbe::detach]. /// /// The cookie is supported since kernel 5.15, and it is made available to - /// the eBPF program via the `bpf_get_attach_cookie()` helper. - pub fn attach<'loc, T: AsRef, Loc: Into>>( + /// the eBPF program via the `bpf_get_attach_cookie()` helper. The `point` + /// argument may be just a location (no cookie) or a [`UProbeAttachPoint`], + /// only the latter sets the cookie explicitly. + pub fn attach<'a, T: AsRef, Point: Into>>( &mut self, - location: Loc, + point: Point, target: T, pid: Option, - cookie: Option, ) -> Result { + let UProbeAttachPoint { location, cookie } = point.into(); let proc_map = pid.map(ProcMap::new).transpose()?; let path = resolve_attach_path(target.as_ref(), proc_map.as_ref())?; - let (symbol, offset) = match location.into() { + let (symbol, offset) = match location { UProbeAttachLocation::Symbol(s) => (Some(s), 0), UProbeAttachLocation::SymbolOffset(s, offset) => (Some(s), offset), UProbeAttachLocation::AbsoluteOffset(offset) => (None, offset), diff --git a/test/integration-test/src/tests/array.rs b/test/integration-test/src/tests/array.rs index 8a78b246f..7ee9359a3 100644 --- a/test/integration-test/src/tests/array.rs +++ b/test/integration-test/src/tests/array.rs @@ -55,7 +55,7 @@ fn test_array() { for (prog_name, symbol) in progs_and_symbols { let prog: &mut UProbe = ebpf.program_mut(prog_name).unwrap().try_into().unwrap(); prog.load().unwrap(); - prog.attach(symbol, "/proc/self/exe", None, None).unwrap(); + prog.attach(symbol, "/proc/self/exe", None).unwrap(); } let result_array = ebpf.map(result_map).unwrap(); let result_array = Array::<_, u32>::try_from(result_array).unwrap(); diff --git a/test/integration-test/src/tests/bpf_probe_read.rs b/test/integration-test/src/tests/bpf_probe_read.rs index 98d491edf..b2c23edba 100644 --- a/test/integration-test/src/tests/bpf_probe_read.rs +++ b/test/integration-test/src/tests/bpf_probe_read.rs @@ -99,8 +99,7 @@ fn load_and_attach_uprobe(prog_name: &str, func_name: &str, bytes: &[u8]) -> Ebp let prog: &mut UProbe = bpf.program_mut(prog_name).unwrap().try_into().unwrap(); prog.load().unwrap(); - prog.attach(func_name, "/proc/self/exe", None, None) - .unwrap(); + prog.attach(func_name, "/proc/self/exe", None).unwrap(); bpf } diff --git a/test/integration-test/src/tests/btf_relocations.rs b/test/integration-test/src/tests/btf_relocations.rs index 0c64c426a..01556b22a 100644 --- a/test/integration-test/src/tests/btf_relocations.rs +++ b/test/integration-test/src/tests/btf_relocations.rs @@ -90,12 +90,7 @@ fn relocation_tests( let program: &mut UProbe = bpf.program_mut("program").unwrap().try_into().unwrap(); program.load().unwrap(); program - .attach( - "trigger_btf_relocations_program", - "/proc/self/exe", - None, - None, - ) + .attach("trigger_btf_relocations_program", "/proc/self/exe", None) .unwrap(); trigger_btf_relocations_program(); diff --git a/test/integration-test/src/tests/info.rs b/test/integration-test/src/tests/info.rs index 20c92c754..b40b9599f 100644 --- a/test/integration-test/src/tests/info.rs +++ b/test/integration-test/src/tests/info.rs @@ -65,9 +65,7 @@ fn test_loaded_programs() { }; // Ensure we can perform basic operations on the re-created program. - let res = p - .attach("uprobe_function", "/proc/self/exe", None, None) - .unwrap(); + let res = p.attach("uprobe_function", "/proc/self/exe", None).unwrap(); // Ensure the program can be detached. p.detach(res).unwrap(); diff --git a/test/integration-test/src/tests/linear_data_structures.rs b/test/integration-test/src/tests/linear_data_structures.rs index 12e0be67b..210b3152d 100644 --- a/test/integration-test/src/tests/linear_data_structures.rs +++ b/test/integration-test/src/tests/linear_data_structures.rs @@ -47,7 +47,7 @@ macro_rules! define_linear_ds_host_test { ] { let prog: &mut UProbe = bpf.program_mut(prog_name).unwrap().try_into().unwrap(); prog.load().unwrap(); - prog.attach(symbol, "/proc/self/exe", None, None).unwrap(); + prog.attach(symbol, "/proc/self/exe", None).unwrap(); } let array_map = bpf.map("RESULT").unwrap(); let array = Array::<_, u64>::try_from(array_map).unwrap(); diff --git a/test/integration-test/src/tests/load.rs b/test/integration-test/src/tests/load.rs index 26046824f..df19b576d 100644 --- a/test/integration-test/src/tests/load.rs +++ b/test/integration-test/src/tests/load.rs @@ -56,7 +56,7 @@ fn multiple_btf_maps() { let prog: &mut UProbe = bpf.program_mut("bpf_prog").unwrap().try_into().unwrap(); prog.load().unwrap(); - prog.attach("trigger_bpf_program", "/proc/self/exe", None, None) + prog.attach("trigger_bpf_program", "/proc/self/exe", None) .unwrap(); trigger_bpf_program(); @@ -106,7 +106,7 @@ fn pin_lifecycle_multiple_btf_maps() { let prog: &mut UProbe = bpf.program_mut("bpf_prog").unwrap().try_into().unwrap(); prog.load().unwrap(); - prog.attach("trigger_bpf_program", "/proc/self/exe", None, None) + prog.attach("trigger_bpf_program", "/proc/self/exe", None) .unwrap(); trigger_bpf_program(); @@ -336,7 +336,7 @@ fn basic_uprobe() { let program_name = "test_uprobe"; let attach = |prog: &mut P| { - prog.attach("uprobe_function", "/proc/self/exe", None, None) + prog.attach("uprobe_function", "/proc/self/exe", None) .unwrap() }; run_unload_program_test( @@ -582,7 +582,7 @@ fn pin_lifecycle_uprobe() { let program_name = "test_uprobe"; let attach = |prog: &mut P| { - prog.attach("uprobe_function", "/proc/self/exe", None, None) + prog.attach("uprobe_function", "/proc/self/exe", None) .unwrap() }; let program_pin = "/sys/fs/bpf/aya-uprobe-test-prog"; diff --git a/test/integration-test/src/tests/log.rs b/test/integration-test/src/tests/log.rs index 58d89c8ff..1feb7321e 100644 --- a/test/integration-test/src/tests/log.rs +++ b/test/integration-test/src/tests/log.rs @@ -69,7 +69,7 @@ fn log() { let prog: &mut UProbe = bpf.program_mut("test_log").unwrap().try_into().unwrap(); prog.load().unwrap(); - prog.attach("trigger_ebpf_program", "/proc/self/exe", None, None) + prog.attach("trigger_ebpf_program", "/proc/self/exe", None) .unwrap(); // Call the function that the uprobe is attached to, so it starts logging. @@ -248,7 +248,7 @@ fn log_level_only_error_warn() { let prog: &mut UProbe = bpf.program_mut("test_log").unwrap().try_into().unwrap(); prog.load().unwrap(); - prog.attach("trigger_ebpf_program", "/proc/self/exe", None, None) + prog.attach("trigger_ebpf_program", "/proc/self/exe", None) .unwrap(); trigger_ebpf_program(); @@ -303,7 +303,7 @@ fn log_level_prevents_verif_fail() { .try_into() .unwrap(); prog.load().unwrap(); - prog.attach("trigger_ebpf_program", "/proc/self/exe", None, None) + prog.attach("trigger_ebpf_program", "/proc/self/exe", None) .unwrap(); trigger_ebpf_program(); diff --git a/test/integration-test/src/tests/maps_disjoint.rs b/test/integration-test/src/tests/maps_disjoint.rs index 79f6fe236..f6493c725 100644 --- a/test/integration-test/src/tests/maps_disjoint.rs +++ b/test/integration-test/src/tests/maps_disjoint.rs @@ -20,13 +20,8 @@ fn test_maps_disjoint() { .unwrap(); prog.load().unwrap(); - prog.attach( - "trigger_ebpf_program_maps_disjoint", - "/proc/self/exe", - None, - None, - ) - .unwrap(); + prog.attach("trigger_ebpf_program_maps_disjoint", "/proc/self/exe", None) + .unwrap(); let [foo, bar, baz] = bpf.maps_disjoint_mut(["FOO", "BAR", "BAZ"]); diff --git a/test/integration-test/src/tests/relocations.rs b/test/integration-test/src/tests/relocations.rs index 88b3e2b42..3be626be9 100644 --- a/test/integration-test/src/tests/relocations.rs +++ b/test/integration-test/src/tests/relocations.rs @@ -55,7 +55,7 @@ fn load_and_attach(name: &str, bytes: &[u8]) -> Ebpf { let prog: &mut UProbe = bpf.program_mut(name).unwrap().try_into().unwrap(); prog.load().unwrap(); - prog.attach("trigger_relocations_program", "/proc/self/exe", None, None) + prog.attach("trigger_relocations_program", "/proc/self/exe", None) .unwrap(); bpf diff --git a/test/integration-test/src/tests/ring_buf.rs b/test/integration-test/src/tests/ring_buf.rs index 273dc25f3..002f9c6ee 100644 --- a/test/integration-test/src/tests/ring_buf.rs +++ b/test/integration-test/src/tests/ring_buf.rs @@ -66,13 +66,8 @@ impl RingBufTest { .try_into() .unwrap(); prog.load().unwrap(); - prog.attach( - "ring_buf_trigger_ebpf_program", - "/proc/self/exe", - None, - None, - ) - .unwrap(); + prog.attach("ring_buf_trigger_ebpf_program", "/proc/self/exe", None) + .unwrap(); Self { _bpf: bpf, diff --git a/test/integration-test/src/tests/strncmp.rs b/test/integration-test/src/tests/strncmp.rs index 9428e0000..04cf94f0b 100644 --- a/test/integration-test/src/tests/strncmp.rs +++ b/test/integration-test/src/tests/strncmp.rs @@ -29,7 +29,7 @@ fn bpf_strncmp() { .unwrap(); prog.load().unwrap(); - prog.attach("trigger_bpf_strncmp", "/proc/self/exe", None, None) + prog.attach("trigger_bpf_strncmp", "/proc/self/exe", None) .unwrap(); } diff --git a/test/integration-test/src/tests/uprobe_cookie.rs b/test/integration-test/src/tests/uprobe_cookie.rs index e90f7bbe6..cf7b5fdcd 100644 --- a/test/integration-test/src/tests/uprobe_cookie.rs +++ b/test/integration-test/src/tests/uprobe_cookie.rs @@ -1,4 +1,9 @@ -use aya::{EbpfLoader, maps::ring_buf::RingBuf, programs::UProbe, util::KernelVersion}; +use aya::{ + EbpfLoader, + maps::ring_buf::RingBuf, + programs::{UProbe, uprobe::UProbeAttachPoint}, + util::KernelVersion, +}; #[test_log::test] fn test_uprobe_cookie() { @@ -25,9 +30,16 @@ fn test_uprobe_cookie() { prog.load().unwrap(); const PROG_A: &str = "uprobe_cookie_trigger_ebpf_program_a"; const PROG_B: &str = "uprobe_cookie_trigger_ebpf_program_b"; - let attach = |prog: &mut UProbe, fn_name, cookie| { - prog.attach(fn_name, "/proc/self/exe", None, Some(cookie)) - .unwrap() + let attach = |prog: &mut UProbe, fn_name: &str, cookie| { + prog.attach( + UProbeAttachPoint { + location: fn_name.into(), + cookie: Some(cookie), + }, + "/proc/self/exe", + None, + ) + .unwrap() }; // Note that the arguments we pass to the functions are meaningless, but we diff --git a/xtask/public-api/aya.txt b/xtask/public-api/aya.txt index 3b6618be5..6f5165912 100644 --- a/xtask/public-api/aya.txt +++ b/xtask/public-api/aya.txt @@ -7414,7 +7414,7 @@ pub fn aya::programs::uprobe::UProbeError::from(t: T) -> T pub struct aya::programs::uprobe::UProbe impl aya::programs::uprobe::UProbe pub const aya::programs::uprobe::UProbe::PROGRAM_TYPE: aya::programs::ProgramType -pub fn aya::programs::uprobe::UProbe::attach<'loc, T: core::convert::AsRef, Loc: core::convert::Into>>(&mut self, location: Loc, target: T, pid: core::option::Option, cookie: core::option::Option) -> core::result::Result +pub fn aya::programs::uprobe::UProbe::attach<'a, T: core::convert::AsRef, Point: core::convert::Into>>(&mut self, point: Point, target: T, pid: core::option::Option) -> core::result::Result pub fn aya::programs::uprobe::UProbe::from_pin>(path: P, kind: aya::programs::ProbeKind) -> core::result::Result pub fn aya::programs::uprobe::UProbe::kind(&self) -> aya::programs::ProbeKind pub fn aya::programs::uprobe::UProbe::load(&mut self) -> core::result::Result<(), aya::programs::ProgramError> @@ -7464,6 +7464,33 @@ impl core::borrow::BorrowMut for aya::programs::uprobe::UProbe where T: ?c pub fn aya::programs::uprobe::UProbe::borrow_mut(&mut self) -> &mut T impl core::convert::From for aya::programs::uprobe::UProbe pub fn aya::programs::uprobe::UProbe::from(t: T) -> T +pub struct aya::programs::uprobe::UProbeAttachPoint<'a> +pub aya::programs::uprobe::UProbeAttachPoint::cookie: core::option::Option +pub aya::programs::uprobe::UProbeAttachPoint::location: aya::programs::uprobe::UProbeAttachLocation<'a> +impl<'a, L: core::convert::Into>> core::convert::From for aya::programs::uprobe::UProbeAttachPoint<'a> +pub fn aya::programs::uprobe::UProbeAttachPoint<'a>::from(location: L) -> Self +impl<'a> core::marker::Freeze for aya::programs::uprobe::UProbeAttachPoint<'a> +impl<'a> core::marker::Send for aya::programs::uprobe::UProbeAttachPoint<'a> +impl<'a> core::marker::Sync for aya::programs::uprobe::UProbeAttachPoint<'a> +impl<'a> core::marker::Unpin for aya::programs::uprobe::UProbeAttachPoint<'a> +impl<'a> core::panic::unwind_safe::RefUnwindSafe for aya::programs::uprobe::UProbeAttachPoint<'a> +impl<'a> core::panic::unwind_safe::UnwindSafe for aya::programs::uprobe::UProbeAttachPoint<'a> +impl core::convert::Into for aya::programs::uprobe::UProbeAttachPoint<'a> where U: core::convert::From +pub fn aya::programs::uprobe::UProbeAttachPoint<'a>::into(self) -> U +impl core::convert::TryFrom for aya::programs::uprobe::UProbeAttachPoint<'a> where U: core::convert::Into +pub type aya::programs::uprobe::UProbeAttachPoint<'a>::Error = core::convert::Infallible +pub fn aya::programs::uprobe::UProbeAttachPoint<'a>::try_from(value: U) -> core::result::Result>::Error> +impl core::convert::TryInto for aya::programs::uprobe::UProbeAttachPoint<'a> where U: core::convert::TryFrom +pub type aya::programs::uprobe::UProbeAttachPoint<'a>::Error = >::Error +pub fn aya::programs::uprobe::UProbeAttachPoint<'a>::try_into(self) -> core::result::Result>::Error> +impl core::any::Any for aya::programs::uprobe::UProbeAttachPoint<'a> where T: 'static + ?core::marker::Sized +pub fn aya::programs::uprobe::UProbeAttachPoint<'a>::type_id(&self) -> core::any::TypeId +impl core::borrow::Borrow for aya::programs::uprobe::UProbeAttachPoint<'a> where T: ?core::marker::Sized +pub fn aya::programs::uprobe::UProbeAttachPoint<'a>::borrow(&self) -> &T +impl core::borrow::BorrowMut for aya::programs::uprobe::UProbeAttachPoint<'a> where T: ?core::marker::Sized +pub fn aya::programs::uprobe::UProbeAttachPoint<'a>::borrow_mut(&mut self) -> &mut T +impl core::convert::From for aya::programs::uprobe::UProbeAttachPoint<'a> +pub fn aya::programs::uprobe::UProbeAttachPoint<'a>::from(t: T) -> T pub struct aya::programs::uprobe::UProbeLink(_) impl aya::programs::links::Link for aya::programs::uprobe::UProbeLink pub type aya::programs::uprobe::UProbeLink::Id = aya::programs::uprobe::UProbeLinkId @@ -10147,7 +10174,7 @@ pub fn aya::programs::trace_point::TracePoint::from(t: T) -> T pub struct aya::programs::UProbe impl aya::programs::uprobe::UProbe pub const aya::programs::uprobe::UProbe::PROGRAM_TYPE: aya::programs::ProgramType -pub fn aya::programs::uprobe::UProbe::attach<'loc, T: core::convert::AsRef, Loc: core::convert::Into>>(&mut self, location: Loc, target: T, pid: core::option::Option, cookie: core::option::Option) -> core::result::Result +pub fn aya::programs::uprobe::UProbe::attach<'a, T: core::convert::AsRef, Point: core::convert::Into>>(&mut self, point: Point, target: T, pid: core::option::Option) -> core::result::Result pub fn aya::programs::uprobe::UProbe::from_pin>(path: P, kind: aya::programs::ProbeKind) -> core::result::Result pub fn aya::programs::uprobe::UProbe::kind(&self) -> aya::programs::ProbeKind pub fn aya::programs::uprobe::UProbe::load(&mut self) -> core::result::Result<(), aya::programs::ProgramError>