diff --git a/aya/src/programs/extension.rs b/aya/src/programs/extension.rs index 36298332..9ebc2d8e 100644 --- a/aya/src/programs/extension.rs +++ b/aya/src/programs/extension.rs @@ -61,8 +61,11 @@ impl Extension { /// Prepares the code included in the extension to replace the code of the function /// `func_name` within the eBPF program represented by the `program` file descriptor. /// This requires that both the [`Extension`] and `program` have had their BTF - /// loaded into the kernel as the verifier must check that the function signatures - /// match. + /// loaded into the kernel. + /// + /// The BPF verifier requires that we specify the target program and function name + /// at load time, so it can identify that the program and target are BTF compatible + /// and to enforce this constraint when programs are attached. /// /// The extension code will be loaded but inactive until it's attached. /// There are no restrictions on what functions may be replaced, so you could replace @@ -79,7 +82,8 @@ impl Extension { /// Attaches the extension. /// - /// Attaches the extension effectively replacing the original target function. + /// Attaches the extension to the program and function name specified at load time, + /// effectively replacing the original target function. /// /// The returned value can be used to detach the extension and restore the /// original function, see [Extension::detach]. @@ -96,10 +100,14 @@ impl Extension { self.data.links.insert(ExtensionLink(FdLink::new(link_fd))) } - /// Attaches the extension to another BTF-compatible program. + /// Attaches the extension to another program. + /// + /// Attaches the extension to a program and/or function other than the one provided + /// at load time. You may only attach to another program/function if the BTF + /// type signature is identical to that which was verified on load. Attempting to + /// attach to an invalid program/function will result in an error. /// - /// Attaches the extension effectively replacing the original target function. - /// program. + /// Once attached, the extension effectively replaces the original target function. /// /// The returned value can be used to detach the extension and restore the /// original function, see [Extension::detach]. @@ -140,23 +148,30 @@ impl Extension { } } +/// Retrieves the FD of the BTF object for the provided `prog_fd` and the BTF ID of the function +/// with the name `func_name` within that BTF object. fn get_btf_info(prog_fd: i32, func_name: &str) -> Result<(RawFd, u32), ProgramError> { + // retrieve program information let info = sys::bpf_obj_get_info_by_fd(prog_fd).map_err(|io_error| ProgramError::SyscallError { call: "bpf_obj_get_info_by_fd".to_owned(), io_error, })?; + // btf_id refers to the ID of the program btf that was loaded with bpf(BPF_BTF_LOAD) if info.btf_id == 0 { return Err(ProgramError::ExtensionError(ExtensionError::NoBTF)); } + // the bpf fd of the BTF object let btf_fd = sys::bpf_btf_get_fd_by_id(info.btf_id).map_err(|io_error| ProgramError::SyscallError { call: "bpf_btf_get_fd_by_id".to_owned(), io_error, })?; + // we need to read the btf bytes into a buffer but we don't know the size ahead of time. + // assume 4kb. if this is too small we can resize based on the size obtained in the response. let mut buf = vec![0u8; 4096]; let btf_info = match sys::btf_obj_get_info_by_fd(btf_fd, &mut buf) { Ok(info) => {