|
|
@ -84,8 +84,17 @@ pub struct Program {
|
|
|
|
pub kernel_version: KernelVersion,
|
|
|
|
pub kernel_version: KernelVersion,
|
|
|
|
/// The section containing the program
|
|
|
|
/// The section containing the program
|
|
|
|
pub section: ProgramSection,
|
|
|
|
pub section: ProgramSection,
|
|
|
|
/// The function
|
|
|
|
/// The section index of the program
|
|
|
|
pub function: Function,
|
|
|
|
pub section_index: usize,
|
|
|
|
|
|
|
|
/// The address of the program
|
|
|
|
|
|
|
|
pub address: u64,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
impl Program {
|
|
|
|
|
|
|
|
/// The key used by [Object::functions]
|
|
|
|
|
|
|
|
pub fn function_key(&self) -> (usize, u64) {
|
|
|
|
|
|
|
|
(self.section_index, self.address)
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// An eBPF function
|
|
|
|
/// An eBPF function
|
|
|
@ -646,7 +655,7 @@ impl Object {
|
|
|
|
Ok(())
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn parse_program(&self, section: &Section) -> Result<Program, ParseError> {
|
|
|
|
fn parse_program(&self, section: &Section) -> Result<(Program, Function), ParseError> {
|
|
|
|
let prog_sec = ProgramSection::from_str(section.name)?;
|
|
|
|
let prog_sec = ProgramSection::from_str(section.name)?;
|
|
|
|
let name = prog_sec.name().to_owned();
|
|
|
|
let name = prog_sec.name().to_owned();
|
|
|
|
|
|
|
|
|
|
|
@ -664,11 +673,7 @@ impl Object {
|
|
|
|
(FuncSecInfo::default(), LineSecInfo::default(), 0, 0)
|
|
|
|
(FuncSecInfo::default(), LineSecInfo::default(), 0, 0)
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
Ok(Program {
|
|
|
|
let function = Function {
|
|
|
|
license: self.license.clone(),
|
|
|
|
|
|
|
|
kernel_version: self.kernel_version,
|
|
|
|
|
|
|
|
section: prog_sec,
|
|
|
|
|
|
|
|
function: Function {
|
|
|
|
|
|
|
|
name,
|
|
|
|
name,
|
|
|
|
address: section.address,
|
|
|
|
address: section.address,
|
|
|
|
section_index: section.index,
|
|
|
|
section_index: section.index,
|
|
|
@ -678,8 +683,18 @@ impl Object {
|
|
|
|
line_info,
|
|
|
|
line_info,
|
|
|
|
func_info_rec_size,
|
|
|
|
func_info_rec_size,
|
|
|
|
line_info_rec_size,
|
|
|
|
line_info_rec_size,
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Ok((
|
|
|
|
|
|
|
|
Program {
|
|
|
|
|
|
|
|
license: self.license.clone(),
|
|
|
|
|
|
|
|
kernel_version: self.kernel_version,
|
|
|
|
|
|
|
|
section: prog_sec,
|
|
|
|
|
|
|
|
section_index: function.section_index.0,
|
|
|
|
|
|
|
|
address: function.address,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
function,
|
|
|
|
|
|
|
|
))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn parse_text_section(&mut self, section: Section) -> Result<(), ParseError> {
|
|
|
|
fn parse_text_section(&mut self, section: Section) -> Result<(), ParseError> {
|
|
|
@ -875,7 +890,8 @@ impl Object {
|
|
|
|
res?
|
|
|
|
res?
|
|
|
|
}
|
|
|
|
}
|
|
|
|
BpfSectionKind::Program => {
|
|
|
|
BpfSectionKind::Program => {
|
|
|
|
let program = self.parse_program(§ion)?;
|
|
|
|
let (program, function) = self.parse_program(§ion)?;
|
|
|
|
|
|
|
|
self.functions.insert(program.function_key(), function);
|
|
|
|
self.programs
|
|
|
|
self.programs
|
|
|
|
.insert(program.section.name().to_owned(), program);
|
|
|
|
.insert(program.section.name().to_owned(), program);
|
|
|
|
if !section.relocations.is_empty() {
|
|
|
|
if !section.relocations.is_empty() {
|
|
|
@ -895,10 +911,10 @@ impl Object {
|
|
|
|
Ok(())
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Sanitize BPF programs.
|
|
|
|
/// Sanitize BPF functions.
|
|
|
|
pub fn sanitize_programs(&mut self, features: &Features) {
|
|
|
|
pub fn sanitize_functions(&mut self, features: &Features) {
|
|
|
|
for program in self.programs.values_mut() {
|
|
|
|
for function in self.functions.values_mut() {
|
|
|
|
program.sanitize(features);
|
|
|
|
function.sanitize(features);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -918,9 +934,9 @@ const BPF_FUNC_PROBE_READ_KERNEL: i32 = 113;
|
|
|
|
const BPF_FUNC_PROBE_READ_USER_STR: i32 = 114;
|
|
|
|
const BPF_FUNC_PROBE_READ_USER_STR: i32 = 114;
|
|
|
|
const BPF_FUNC_PROBE_READ_KERNEL_STR: i32 = 115;
|
|
|
|
const BPF_FUNC_PROBE_READ_KERNEL_STR: i32 = 115;
|
|
|
|
|
|
|
|
|
|
|
|
impl Program {
|
|
|
|
impl Function {
|
|
|
|
fn sanitize(&mut self, features: &Features) {
|
|
|
|
fn sanitize(&mut self, features: &Features) {
|
|
|
|
for inst in &mut self.function.instructions {
|
|
|
|
for inst in &mut self.instructions {
|
|
|
|
if !insn_is_helper_call(inst) {
|
|
|
|
if !insn_is_helper_call(inst) {
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -1652,17 +1668,17 @@ mod tests {
|
|
|
|
|
|
|
|
|
|
|
|
assert_matches!(
|
|
|
|
assert_matches!(
|
|
|
|
obj.parse_program(&fake_section(BpfSectionKind::Program,"kprobe/foo", bytes_of(&fake_ins()))),
|
|
|
|
obj.parse_program(&fake_section(BpfSectionKind::Program,"kprobe/foo", bytes_of(&fake_ins()))),
|
|
|
|
Ok(Program {
|
|
|
|
Ok((Program {
|
|
|
|
license,
|
|
|
|
license,
|
|
|
|
kernel_version: KernelVersion::Any,
|
|
|
|
kernel_version: KernelVersion::Any,
|
|
|
|
section: ProgramSection::KProbe { .. },
|
|
|
|
section: ProgramSection::KProbe { .. },
|
|
|
|
function: Function {
|
|
|
|
.. }, Function {
|
|
|
|
name,
|
|
|
|
name,
|
|
|
|
address: 0,
|
|
|
|
address: 0,
|
|
|
|
section_index: SectionIndex(0),
|
|
|
|
section_index: SectionIndex(0),
|
|
|
|
section_offset: 0,
|
|
|
|
section_offset: 0,
|
|
|
|
instructions,
|
|
|
|
instructions,
|
|
|
|
..} }) if license.to_string_lossy() == "GPL" && name == "foo" && instructions.len() == 1
|
|
|
|
..})) if license.to_string_lossy() == "GPL" && name == "foo" && instructions.len() == 1
|
|
|
|
);
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|