Get verifier logs when loading programs

reviewable/pr641/r1
Tamir Duberstein 2 years ago
parent 4022d349ac
commit efa6a0a13f
No known key found for this signature in database

@ -133,7 +133,7 @@ pub struct BpfLoader<'a> {
bitflags! {
/// Used to set the verifier log level flags in [BpfLoader](BpfLoader::verifier_log_level()).
#[derive(Debug)]
#[derive(Clone, Copy, Debug)]
pub struct VerifierLogLevel: u32 {
/// Sets no verifier logging.
const DISABLE = 0;
@ -349,9 +349,16 @@ impl<'a> BpfLoader<'a> {
/// # Ok::<(), aya::BpfError>(())
/// ```
pub fn load(&mut self, data: &[u8]) -> Result<Bpf, BpfError> {
let verifier_log_level = self.verifier_log_level.bits();
let Self {
btf,
map_pin_path,
globals,
max_entries,
extensions,
verifier_log_level,
} = self;
let mut obj = Object::parse(data)?;
obj.patch_map_data(self.globals.clone())?;
obj.patch_map_data(globals.clone())?;
let btf_fd = if let Some(features) = &FEATURES.btf() {
if let Some(btf) = obj.fixup_and_sanitize_btf(features)? {
@ -364,7 +371,7 @@ impl<'a> BpfLoader<'a> {
None
};
if let Some(btf) = &self.btf {
if let Some(btf) = &btf {
obj.relocate_btf(btf)?;
}
let mut maps = HashMap::new();
@ -375,7 +382,7 @@ impl<'a> BpfLoader<'a> {
continue;
}
match self.max_entries.get(name.as_str()) {
match max_entries.get(name.as_str()) {
Some(size) => obj.set_max_entries(*size),
None => {
if obj.map_type() == BPF_MAP_TYPE_PERF_EVENT_ARRAY as u32
@ -400,7 +407,7 @@ impl<'a> BpfLoader<'a> {
};
let fd = match map.obj.pinning() {
PinningType::ByName => {
let path = match &self.map_pin_path {
let path = match &map_pin_path {
Some(p) => p,
None => return Err(BpfError::NoPinPath),
};
@ -466,72 +473,72 @@ impl<'a> BpfLoader<'a> {
let section = prog_obj.section.clone();
let obj = (prog_obj, function_obj);
let program = if self.extensions.contains(name.as_str()) {
let program = if extensions.contains(name.as_str()) {
Program::Extension(Extension {
data: ProgramData::new(prog_name, obj, btf_fd, verifier_log_level),
data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level),
})
} else {
match &section {
ProgramSection::KProbe { .. } => Program::KProbe(KProbe {
data: ProgramData::new(prog_name, obj, btf_fd, verifier_log_level),
data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level),
kind: ProbeKind::KProbe,
}),
ProgramSection::KRetProbe { .. } => Program::KProbe(KProbe {
data: ProgramData::new(prog_name, obj, btf_fd, verifier_log_level),
data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level),
kind: ProbeKind::KRetProbe,
}),
ProgramSection::UProbe { .. } => Program::UProbe(UProbe {
data: ProgramData::new(prog_name, obj, btf_fd, verifier_log_level),
data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level),
kind: ProbeKind::UProbe,
}),
ProgramSection::URetProbe { .. } => Program::UProbe(UProbe {
data: ProgramData::new(prog_name, obj, btf_fd, verifier_log_level),
data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level),
kind: ProbeKind::URetProbe,
}),
ProgramSection::TracePoint { .. } => Program::TracePoint(TracePoint {
data: ProgramData::new(prog_name, obj, btf_fd, verifier_log_level),
data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level),
}),
ProgramSection::SocketFilter { .. } => {
Program::SocketFilter(SocketFilter {
data: ProgramData::new(prog_name, obj, btf_fd, verifier_log_level),
data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level),
})
}
ProgramSection::Xdp { frags, .. } => {
let mut data =
ProgramData::new(prog_name, obj, btf_fd, verifier_log_level);
ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level);
if *frags {
data.flags = BPF_F_XDP_HAS_FRAGS;
}
Program::Xdp(Xdp { data })
}
ProgramSection::SkMsg { .. } => Program::SkMsg(SkMsg {
data: ProgramData::new(prog_name, obj, btf_fd, verifier_log_level),
data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level),
}),
ProgramSection::CgroupSysctl { .. } => {
Program::CgroupSysctl(CgroupSysctl {
data: ProgramData::new(prog_name, obj, btf_fd, verifier_log_level),
data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level),
})
}
ProgramSection::CgroupSockopt { attach_type, .. } => {
Program::CgroupSockopt(CgroupSockopt {
data: ProgramData::new(prog_name, obj, btf_fd, verifier_log_level),
data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level),
attach_type: *attach_type,
})
}
ProgramSection::SkSkbStreamParser { .. } => Program::SkSkb(SkSkb {
data: ProgramData::new(prog_name, obj, btf_fd, verifier_log_level),
data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level),
kind: SkSkbKind::StreamParser,
}),
ProgramSection::SkSkbStreamVerdict { .. } => Program::SkSkb(SkSkb {
data: ProgramData::new(prog_name, obj, btf_fd, verifier_log_level),
data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level),
kind: SkSkbKind::StreamVerdict,
}),
ProgramSection::SockOps { .. } => Program::SockOps(SockOps {
data: ProgramData::new(prog_name, obj, btf_fd, verifier_log_level),
data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level),
}),
ProgramSection::SchedClassifier { .. } => {
Program::SchedClassifier(SchedClassifier {
data: ProgramData::new(prog_name, obj, btf_fd, verifier_log_level),
data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level),
name: unsafe {
CString::from_vec_unchecked(Vec::from(name.clone()))
.into_boxed_c_str()
@ -539,37 +546,37 @@ impl<'a> BpfLoader<'a> {
})
}
ProgramSection::CgroupSkb { .. } => Program::CgroupSkb(CgroupSkb {
data: ProgramData::new(prog_name, obj, btf_fd, verifier_log_level),
data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level),
expected_attach_type: None,
}),
ProgramSection::CgroupSkbIngress { .. } => Program::CgroupSkb(CgroupSkb {
data: ProgramData::new(prog_name, obj, btf_fd, verifier_log_level),
data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level),
expected_attach_type: Some(CgroupSkbAttachType::Ingress),
}),
ProgramSection::CgroupSkbEgress { .. } => Program::CgroupSkb(CgroupSkb {
data: ProgramData::new(prog_name, obj, btf_fd, verifier_log_level),
data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level),
expected_attach_type: Some(CgroupSkbAttachType::Egress),
}),
ProgramSection::CgroupSockAddr { attach_type, .. } => {
Program::CgroupSockAddr(CgroupSockAddr {
data: ProgramData::new(prog_name, obj, btf_fd, verifier_log_level),
data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level),
attach_type: *attach_type,
})
}
ProgramSection::LircMode2 { .. } => Program::LircMode2(LircMode2 {
data: ProgramData::new(prog_name, obj, btf_fd, verifier_log_level),
data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level),
}),
ProgramSection::PerfEvent { .. } => Program::PerfEvent(PerfEvent {
data: ProgramData::new(prog_name, obj, btf_fd, verifier_log_level),
data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level),
}),
ProgramSection::RawTracePoint { .. } => {
Program::RawTracePoint(RawTracePoint {
data: ProgramData::new(prog_name, obj, btf_fd, verifier_log_level),
data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level),
})
}
ProgramSection::Lsm { sleepable, .. } => {
let mut data =
ProgramData::new(prog_name, obj, btf_fd, verifier_log_level);
ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level);
if *sleepable {
data.flags = BPF_F_SLEEPABLE;
}
@ -577,30 +584,30 @@ impl<'a> BpfLoader<'a> {
}
ProgramSection::BtfTracePoint { .. } => {
Program::BtfTracePoint(BtfTracePoint {
data: ProgramData::new(prog_name, obj, btf_fd, verifier_log_level),
data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level),
})
}
ProgramSection::FEntry { .. } => Program::FEntry(FEntry {
data: ProgramData::new(prog_name, obj, btf_fd, verifier_log_level),
data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level),
}),
ProgramSection::FExit { .. } => Program::FExit(FExit {
data: ProgramData::new(prog_name, obj, btf_fd, verifier_log_level),
data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level),
}),
ProgramSection::Extension { .. } => Program::Extension(Extension {
data: ProgramData::new(prog_name, obj, btf_fd, verifier_log_level),
data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level),
}),
ProgramSection::SkLookup { .. } => Program::SkLookup(SkLookup {
data: ProgramData::new(prog_name, obj, btf_fd, verifier_log_level),
data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level),
}),
ProgramSection::CgroupSock { attach_type, .. } => {
Program::CgroupSock(CgroupSock {
data: ProgramData::new(prog_name, obj, btf_fd, verifier_log_level),
data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level),
attach_type: *attach_type,
})
}
ProgramSection::CgroupDevice { .. } => {
Program::CgroupDevice(CgroupDevice {
data: ProgramData::new(prog_name, obj, btf_fd, verifier_log_level),
data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level),
})
}
}
@ -907,8 +914,9 @@ pub enum BpfError {
}
fn load_btf(raw_btf: Vec<u8>) -> Result<RawFd, BtfError> {
let (ret, verifier_log) =
retry_with_verifier_logs(10, |logger| bpf_load_btf(raw_btf.as_slice(), logger));
let (ret, verifier_log) = retry_with_verifier_logs(10, |logger| {
bpf_load_btf(raw_btf.as_slice(), logger, VerifierLogLevel::default())
});
match ret {
Ok(fd) => Ok(fd as RawFd),
Err((_, io_error)) => Err(BtfError::LoadError {

@ -113,6 +113,7 @@ use crate::{
bpf_prog_get_fd_by_id, bpf_prog_get_info_by_fd, bpf_prog_get_next_id, bpf_prog_query,
retry_with_verifier_logs, BpfLoadProgramAttrs,
},
VerifierLogLevel,
};
/// Error type returned when working with programs.
@ -413,7 +414,7 @@ pub(crate) struct ProgramData<T: Link> {
pub(crate) attach_btf_id: Option<u32>,
pub(crate) attach_prog_fd: Option<RawFd>,
pub(crate) btf_fd: Option<RawFd>,
pub(crate) verifier_log_level: u32,
pub(crate) verifier_log_level: VerifierLogLevel,
pub(crate) path: Option<PathBuf>,
pub(crate) flags: u32,
}
@ -423,7 +424,7 @@ impl<T: Link> ProgramData<T> {
name: Option<String>,
obj: (obj::Program, obj::Function),
btf_fd: Option<RawFd>,
verifier_log_level: u32,
verifier_log_level: VerifierLogLevel,
) -> ProgramData<T> {
ProgramData {
name,
@ -474,7 +475,7 @@ impl<T: Link> ProgramData<T> {
attach_btf_id,
attach_prog_fd: None,
btf_fd: None,
verifier_log_level: 0,
verifier_log_level: VerifierLogLevel::default(),
path: Some(path.to_path_buf()),
flags: 0,
})
@ -548,7 +549,20 @@ fn load_program<T: Link>(
prog_type: bpf_prog_type,
data: &mut ProgramData<T>,
) -> Result<(), ProgramError> {
let ProgramData { obj, fd, .. } = data;
let ProgramData {
name,
obj,
fd,
links: _,
expected_attach_type,
attach_btf_obj_fd,
attach_btf_id,
attach_prog_fd,
btf_fd,
verifier_log_level,
path: _,
flags,
} = data;
if fd.is_some() {
return Err(ProgramError::AlreadyLoaded);
}
@ -581,7 +595,7 @@ fn load_program<T: Link>(
_ => (*kernel_version).into(),
};
let prog_name = if let Some(name) = &data.name {
let prog_name = if let Some(name) = name {
let mut name = name.clone();
if name.len() > 15 {
name.truncate(15);
@ -599,21 +613,20 @@ fn load_program<T: Link>(
insns: instructions,
license,
kernel_version: target_kernel_version,
expected_attach_type: data.expected_attach_type,
prog_btf_fd: data.btf_fd,
attach_btf_obj_fd: data.attach_btf_obj_fd,
attach_btf_id: data.attach_btf_id,
attach_prog_fd: data.attach_prog_fd,
expected_attach_type: *expected_attach_type,
prog_btf_fd: *btf_fd,
attach_btf_obj_fd: *attach_btf_obj_fd,
attach_btf_id: *attach_btf_id,
attach_prog_fd: *attach_prog_fd,
func_info_rec_size: *func_info_rec_size,
func_info: func_info.clone(),
line_info_rec_size: *line_info_rec_size,
line_info: line_info.clone(),
flags: data.flags,
flags: *flags,
};
let verifier_log_level = data.verifier_log_level;
let (ret, verifier_log) = retry_with_verifier_logs(10, |logger| {
bpf_load_program(&attr, logger, verifier_log_level)
bpf_load_program(&attr, logger, *verifier_log_level)
});
match ret {

@ -29,7 +29,7 @@ use crate::{
copy_instructions,
},
sys::{kernel_version, syscall, SysResult, Syscall},
Btf, Pod, BPF_OBJ_NAME_LEN,
Btf, Pod, VerifierLogLevel, BPF_OBJ_NAME_LEN,
};
pub(crate) fn bpf_create_map(name: &CStr, def: &obj::Map, btf_fd: Option<RawFd>) -> SysResult {
@ -125,7 +125,7 @@ pub(crate) struct BpfLoadProgramAttrs<'a> {
pub(crate) fn bpf_load_program(
aya_attr: &BpfLoadProgramAttrs,
log_buf: &mut [u8],
verifier_log_level: u32,
verifier_log_level: VerifierLogLevel,
) -> SysResult {
let mut attr = unsafe { mem::zeroed::<bpf_attr>() };
@ -170,7 +170,7 @@ pub(crate) fn bpf_load_program(
}
}
if !log_buf.is_empty() {
u.log_level = verifier_log_level;
u.log_level = verifier_log_level.bits();
u.log_buf = log_buf.as_mut_ptr() as u64;
u.log_size = log_buf.len() as u32;
}
@ -543,13 +543,17 @@ pub(crate) fn bpf_raw_tracepoint_open(name: Option<&CStr>, prog_fd: RawFd) -> Sy
sys_bpf(bpf_cmd::BPF_RAW_TRACEPOINT_OPEN, &attr)
}
pub(crate) fn bpf_load_btf(raw_btf: &[u8], log_buf: &mut [u8]) -> SysResult {
pub(crate) fn bpf_load_btf(
raw_btf: &[u8],
log_buf: &mut [u8],
verifier_log_level: VerifierLogLevel,
) -> SysResult {
let mut attr = unsafe { mem::zeroed::<bpf_attr>() };
let u = unsafe { &mut attr.__bindgen_anon_7 };
u.btf = raw_btf.as_ptr() as *const _ as u64;
u.btf_size = mem::size_of_val(raw_btf) as u32;
if !log_buf.is_empty() {
u.btf_log_level = 1;
u.btf_log_level = verifier_log_level.bits();
u.btf_log_buf = log_buf.as_mut_ptr() as u64;
u.btf_log_size = log_buf.len() as u32;
}

Loading…
Cancel
Save