|
|
@ -3,7 +3,7 @@ use crate::{
|
|
|
|
obj::{btf::BtfType, copy_instructions},
|
|
|
|
obj::{btf::BtfType, copy_instructions},
|
|
|
|
Btf,
|
|
|
|
Btf,
|
|
|
|
};
|
|
|
|
};
|
|
|
|
use libc::{c_char, c_long, close, ENOENT};
|
|
|
|
use libc::{c_char, c_long, close, ENOENT, ENOSPC};
|
|
|
|
|
|
|
|
|
|
|
|
use std::{
|
|
|
|
use std::{
|
|
|
|
cmp::{self, min},
|
|
|
|
cmp::{self, min},
|
|
|
@ -78,19 +78,21 @@ pub(crate) struct BpfLoadProgramAttrs<'a> {
|
|
|
|
pub(crate) attach_btf_obj_fd: Option<u32>,
|
|
|
|
pub(crate) attach_btf_obj_fd: Option<u32>,
|
|
|
|
pub(crate) attach_btf_id: Option<u32>,
|
|
|
|
pub(crate) attach_btf_id: Option<u32>,
|
|
|
|
pub(crate) attach_prog_fd: Option<RawFd>,
|
|
|
|
pub(crate) attach_prog_fd: Option<RawFd>,
|
|
|
|
pub(crate) log: &'a mut VerifierLog,
|
|
|
|
|
|
|
|
pub(crate) func_info_rec_size: usize,
|
|
|
|
pub(crate) func_info_rec_size: usize,
|
|
|
|
pub(crate) func_info: FuncSecInfo,
|
|
|
|
pub(crate) func_info: FuncSecInfo,
|
|
|
|
pub(crate) line_info_rec_size: usize,
|
|
|
|
pub(crate) line_info_rec_size: usize,
|
|
|
|
pub(crate) line_info: LineSecInfo,
|
|
|
|
pub(crate) line_info: LineSecInfo,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub(crate) fn bpf_load_program(aya_attr: BpfLoadProgramAttrs) -> SysResult {
|
|
|
|
pub(crate) fn bpf_load_program(
|
|
|
|
|
|
|
|
aya_attr: &BpfLoadProgramAttrs,
|
|
|
|
|
|
|
|
logger: &mut VerifierLog,
|
|
|
|
|
|
|
|
) -> SysResult {
|
|
|
|
let mut attr = unsafe { mem::zeroed::<bpf_attr>() };
|
|
|
|
let mut attr = unsafe { mem::zeroed::<bpf_attr>() };
|
|
|
|
|
|
|
|
|
|
|
|
let u = unsafe { &mut attr.__bindgen_anon_3 };
|
|
|
|
let u = unsafe { &mut attr.__bindgen_anon_3 };
|
|
|
|
|
|
|
|
|
|
|
|
if let Some(prog_name) = aya_attr.name {
|
|
|
|
if let Some(prog_name) = &aya_attr.name {
|
|
|
|
let mut name: [c_char; 16] = [0; 16];
|
|
|
|
let mut name: [c_char; 16] = [0; 16];
|
|
|
|
let name_bytes = prog_name.to_bytes();
|
|
|
|
let name_bytes = prog_name.to_bytes();
|
|
|
|
let len = min(name.len(), name_bytes.len());
|
|
|
|
let len = min(name.len(), name_bytes.len());
|
|
|
@ -127,7 +129,7 @@ pub(crate) fn bpf_load_program(aya_attr: BpfLoadProgramAttrs) -> SysResult {
|
|
|
|
u.func_info_rec_size = aya_attr.func_info_rec_size as u32;
|
|
|
|
u.func_info_rec_size = aya_attr.func_info_rec_size as u32;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
let log_buf = aya_attr.log.buf();
|
|
|
|
let log_buf = logger.buf();
|
|
|
|
if log_buf.capacity() > 0 {
|
|
|
|
if log_buf.capacity() > 0 {
|
|
|
|
u.log_level = 7;
|
|
|
|
u.log_level = 7;
|
|
|
|
u.log_buf = log_buf.as_mut_ptr() as u64;
|
|
|
|
u.log_buf = log_buf.as_mut_ptr() as u64;
|
|
|
@ -443,7 +445,7 @@ pub(crate) fn bpf_raw_tracepoint_open(name: Option<&CStr>, prog_fd: RawFd) -> Sy
|
|
|
|
sys_bpf(bpf_cmd::BPF_RAW_TRACEPOINT_OPEN, &attr)
|
|
|
|
sys_bpf(bpf_cmd::BPF_RAW_TRACEPOINT_OPEN, &attr)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub(crate) fn bpf_load_btf(raw_btf: &[u8], log: &mut VerifierLog) -> Result<RawFd, io::Error> {
|
|
|
|
pub(crate) fn bpf_load_btf(raw_btf: &[u8], log: &mut VerifierLog) -> SysResult {
|
|
|
|
let mut attr = unsafe { mem::zeroed::<bpf_attr>() };
|
|
|
|
let mut attr = unsafe { mem::zeroed::<bpf_attr>() };
|
|
|
|
let u = unsafe { &mut attr.__bindgen_anon_7 };
|
|
|
|
let u = unsafe { &mut attr.__bindgen_anon_7 };
|
|
|
|
u.btf = raw_btf.as_ptr() as *const _ as u64;
|
|
|
|
u.btf = raw_btf.as_ptr() as *const _ as u64;
|
|
|
@ -454,10 +456,7 @@ pub(crate) fn bpf_load_btf(raw_btf: &[u8], log: &mut VerifierLog) -> Result<RawF
|
|
|
|
u.btf_log_buf = log_buf.as_mut_ptr() as u64;
|
|
|
|
u.btf_log_buf = log_buf.as_mut_ptr() as u64;
|
|
|
|
u.btf_log_size = log_buf.capacity() as u32;
|
|
|
|
u.btf_log_size = log_buf.capacity() as u32;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
match sys_bpf(bpf_cmd::BPF_BTF_LOAD, &attr) {
|
|
|
|
sys_bpf(bpf_cmd::BPF_BTF_LOAD, &attr)
|
|
|
|
Ok(v) => Ok(v as RawFd),
|
|
|
|
|
|
|
|
Err((_, err)) => Err(err),
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub(crate) fn bpf_btf_get_fd_by_id(id: u32) -> Result<RawFd, io::Error> {
|
|
|
|
pub(crate) fn bpf_btf_get_fd_by_id(id: u32) -> Result<RawFd, io::Error> {
|
|
|
@ -733,3 +732,37 @@ pub(crate) fn is_btf_type_tag_supported() -> bool {
|
|
|
|
pub fn sys_bpf(cmd: bpf_cmd, attr: &bpf_attr) -> SysResult {
|
|
|
|
pub fn sys_bpf(cmd: bpf_cmd, attr: &bpf_attr) -> SysResult {
|
|
|
|
syscall(Syscall::Bpf { cmd, attr })
|
|
|
|
syscall(Syscall::Bpf { cmd, attr })
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pub(crate) fn retry_with_verifier_logs<F>(
|
|
|
|
|
|
|
|
max_retries: usize,
|
|
|
|
|
|
|
|
log: &mut VerifierLog,
|
|
|
|
|
|
|
|
f: F,
|
|
|
|
|
|
|
|
) -> SysResult
|
|
|
|
|
|
|
|
where
|
|
|
|
|
|
|
|
F: Fn(&mut VerifierLog) -> SysResult,
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
// 1. Try the syscall
|
|
|
|
|
|
|
|
let ret = f(log);
|
|
|
|
|
|
|
|
if ret.is_ok() {
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 2. Grow the log buffer so we can capture verifier output
|
|
|
|
|
|
|
|
// Retry this up to max_retries times
|
|
|
|
|
|
|
|
log.grow();
|
|
|
|
|
|
|
|
let mut retries = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
loop {
|
|
|
|
|
|
|
|
let ret = f(log);
|
|
|
|
|
|
|
|
match ret {
|
|
|
|
|
|
|
|
Err((v, io_error)) if retries == 0 || io_error.raw_os_error() == Some(ENOSPC) => {
|
|
|
|
|
|
|
|
if retries == max_retries {
|
|
|
|
|
|
|
|
return Err((v, io_error));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
retries += 1;
|
|
|
|
|
|
|
|
log.grow();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
r => return r,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|