From 89b5dd32ede08d3aeb5a07cf980f8af8ff326445 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alessandro=C2=A0Decina?= Date: Mon, 17 Jan 2022 08:11:56 +0000 Subject: [PATCH 1/2] btf: run fixup in place --- aya/src/obj/btf/btf.rs | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/aya/src/obj/btf/btf.rs b/aya/src/obj/btf/btf.rs index 1b4bc3a7..cef9e924 100644 --- a/aya/src/obj/btf/btf.rs +++ b/aya/src/obj/btf/btf.rs @@ -437,11 +437,8 @@ impl Btf { section_sizes: &HashMap, symbol_offsets: &HashMap, ) -> Result<(), BtfError> { - // FIXME: there is probably a more elegant way of doing operation in place - // for now, and to keep on the good side of the borrow checker, we'll create - // a new Vec and populate it as we go - let mut types = vec![]; - for t in &self.types { + let mut types = self.types.split_off(0); + for t in &mut types { let kind = t.kind()?.unwrap_or_default(); // datasec sizes aren't set by llvm // we need to fix them here before loading the btf to the kernel @@ -451,18 +448,16 @@ impl Btf { // While I figure out if this needs fixing in the Kernel or LLVM, we'll // do a fixup here ty.name_off = 0; - types.push(BtfType::Ptr(ty)); } BtfType::DataSec(mut ty, data) => { // Start DataSec Fixups - let sec_name = self.type_name(t)?.ok_or(BtfError::InvalidTypeInfo)?; + let sec_name = self.string_at(ty.name_off)?; let name = sec_name.to_string(); // There are cases when the compiler does indeed populate the // size. If we hit this case, push to the types vector and // continue if unsafe { ty.__bindgen_anon_1.size > 0 } { debug!("{} {}: fixup not required", kind, name); - types.push(BtfType::DataSec(ty, data.clone())); continue; } @@ -481,7 +476,6 @@ impl Btf { // we need to get the offset from the ELF file. // This was also cached during initial parsing and // we can query by name in symbol_offsets - let mut adjusted_data: Vec = vec![]; for d in data { let var_type = self.type_by_id(d.type_)?; let var_kind = var_type.kind()?.unwrap(); @@ -492,7 +486,6 @@ impl Btf { "{} {}: {} {}: fixup not required", kind, name, var_kind, var_name ); - adjusted_data.push(*d); continue; } @@ -501,11 +494,7 @@ impl Btf { symbol_name: var_name.clone(), }, )?; - adjusted_data.push(btf_var_secinfo { - type_: d.type_, - offset: *offset as u32, - size: d.size, - }); + d.offset = *offset as u32; debug!( "{} {}: {} {}: fixup offset {}", kind, name, var_kind, var_name, offset @@ -514,11 +503,9 @@ impl Btf { return Err(BtfError::InvalidDatasec); } } - types.push(BtfType::DataSec(ty, adjusted_data)) } // The type does not need fixing up - // Push it to the new types vec unmodified - ty => types.push(ty.clone()), + _ => {} } } self.types = types; From 9ba2e147a1a82e97849cc8b7ca524550803ec3a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alessandro=C2=A0Decina?= Date: Mon, 17 Jan 2022 08:13:43 +0000 Subject: [PATCH 2/2] btf: fixup func protos If an argument has a type, it must also have a name, see btf_func_check in the kernel. Given: SEC("lsm/syslog") int BPF_PROG(syslog_audit, int type, int ret_prev) { return 0; } Fixes: error: BTF error: the BPF_BTF_LOAD syscall failed. Verifier output: magic: 0xeb9f version: 1 flags: 0x0 hdr_len: 24 type_off: 0 type_len: 76 str_off: 76 str_len: 128 btf_total_size: 228 [1] FUNC_PROTO (anon) return=2 args=(3 (anon)) [2] INT int size=4 bits_offset=0 nr_bits=32 encoding=SIGNED [3] PTR (anon) type_id=4 [4] INT long long unsigned int size=8 bits_offset=0 nr_bits=64 encoding=(none) [5] FUNC syslog_audit type_id=1 [5] FUNC syslog_audit type_id=1 Invalid arg#1 : Invalid argument (os error 22) --- aya/src/obj/btf/btf.rs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/aya/src/obj/btf/btf.rs b/aya/src/obj/btf/btf.rs index cef9e924..04e6d4a7 100644 --- a/aya/src/obj/btf/btf.rs +++ b/aya/src/obj/btf/btf.rs @@ -15,9 +15,7 @@ use object::Endianness; use thiserror::Error; use crate::{ - generated::{ - btf_enum, btf_ext_header, btf_func_linkage, btf_header, btf_member, btf_var_secinfo, - }, + generated::{btf_enum, btf_ext_header, btf_func_linkage, btf_header, btf_member}, obj::btf::{relocation::Relocation, BtfKind, BtfType}, util::bytes_of, Features, @@ -504,6 +502,13 @@ impl Btf { } } } + BtfType::FuncProto(_ty, params) => { + for (i, mut param) in params.iter_mut().enumerate() { + if param.name_off == 0 && param.type_ != 0 { + param.name_off = self.add_string(format!("param{}", i)); + } + } + } // The type does not need fixing up _ => {} } @@ -860,7 +865,7 @@ pub(crate) struct SecInfo<'a> { #[cfg(test)] mod tests { - use crate::generated::{btf_param, BTF_INT_SIGNED, BTF_VAR_STATIC}; + use crate::generated::{btf_param, btf_var_secinfo, BTF_INT_SIGNED, BTF_VAR_STATIC}; use super::*;