Merge pull request #605 from marysaka/fix/global-data-reloc-ancient-kernels

aya: Do not create data maps on kernel without global data support
pull/608/head
Alessandro Decina 2 years ago committed by GitHub
commit 9c437aafd9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -44,6 +44,7 @@ pub struct Features {
pub bpf_name: bool, pub bpf_name: bool,
pub bpf_probe_read_kernel: bool, pub bpf_probe_read_kernel: bool,
pub bpf_perf_link: bool, pub bpf_perf_link: bool,
pub bpf_global_data: bool,
pub btf: Option<BtfFeatures>, pub btf: Option<BtfFeatures>,
} }

@ -33,10 +33,11 @@ use crate::{
SkMsg, SkSkb, SkSkbKind, SockOps, SocketFilter, TracePoint, UProbe, Xdp, SkMsg, SkSkb, SkSkbKind, SockOps, SocketFilter, TracePoint, UProbe, Xdp,
}, },
sys::{ sys::{
bpf_load_btf, bpf_map_freeze, bpf_map_update_elem_ptr, is_btf_datasec_supported, bpf_load_btf, bpf_map_freeze, bpf_map_update_elem_ptr, is_bpf_global_data_supported,
is_btf_decl_tag_supported, is_btf_float_supported, is_btf_func_global_supported, is_btf_datasec_supported, is_btf_decl_tag_supported, is_btf_float_supported,
is_btf_func_supported, is_btf_supported, is_btf_type_tag_supported, is_perf_link_supported, is_btf_func_global_supported, is_btf_func_supported, is_btf_supported,
is_probe_read_kernel_supported, is_prog_name_supported, retry_with_verifier_logs, is_btf_type_tag_supported, is_perf_link_supported, is_probe_read_kernel_supported,
is_prog_name_supported, retry_with_verifier_logs,
}, },
util::{bytes_of, bytes_of_slice, possible_cpus, VerifierLog, POSSIBLE_CPUS}, util::{bytes_of, bytes_of_slice, possible_cpus, VerifierLog, POSSIBLE_CPUS},
}; };
@ -86,6 +87,7 @@ fn detect_features() -> Features {
bpf_name: is_prog_name_supported(), bpf_name: is_prog_name_supported(),
bpf_probe_read_kernel: is_probe_read_kernel_supported(), bpf_probe_read_kernel: is_probe_read_kernel_supported(),
bpf_perf_link: is_perf_link_supported(), bpf_perf_link: is_perf_link_supported(),
bpf_global_data: is_bpf_global_data_supported(),
btf, btf,
}; };
debug!("BPF Feature Detection: {:#?}", f); debug!("BPF Feature Detection: {:#?}", f);
@ -358,6 +360,12 @@ impl<'a> BpfLoader<'a> {
} }
let mut maps = HashMap::new(); let mut maps = HashMap::new();
for (name, mut obj) in obj.maps.drain() { for (name, mut obj) in obj.maps.drain() {
if let (false, BpfSectionKind::Bss | BpfSectionKind::Data | BpfSectionKind::Rodata) =
(FEATURES.bpf_global_data, obj.section_kind())
{
continue;
}
match self.max_entries.get(name.as_str()) { match self.max_entries.get(name.as_str()) {
Some(size) => obj.set_max_entries(*size), Some(size) => obj.set_max_entries(*size),
None => { None => {

@ -8,13 +8,17 @@ use std::{
}; };
use libc::{c_char, c_long, close, ENOENT, ENOSPC}; use libc::{c_char, c_long, close, ENOENT, ENOSPC};
use obj::{
maps::{bpf_map_def, LegacyMap},
BpfSectionKind,
};
use crate::{ use crate::{
generated::{ generated::{
bpf_attach_type, bpf_attr, bpf_btf_info, bpf_cmd, bpf_insn, bpf_link_info, bpf_map_info, bpf_attach_type, bpf_attr, bpf_btf_info, bpf_cmd, bpf_insn, bpf_link_info, bpf_map_info,
bpf_map_type, bpf_prog_info, bpf_prog_type, BPF_F_REPLACE, bpf_map_type, bpf_prog_info, bpf_prog_type, BPF_F_REPLACE,
}, },
maps::PerCpuValues, maps::{MapData, PerCpuValues},
obj::{ obj::{
self, self,
btf::{ btf::{
@ -661,6 +665,60 @@ pub(crate) fn is_perf_link_supported() -> bool {
false false
} }
pub(crate) fn is_bpf_global_data_supported() -> bool {
let mut attr = unsafe { mem::zeroed::<bpf_attr>() };
let u = unsafe { &mut attr.__bindgen_anon_3 };
let prog: &[u8] = &[
0x18, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ld_pseudo r1, 0x2, 0x0
0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, //
0x7a, 0x01, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, // stdw [r1 + 0x0], 0x2a
0xb7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // mov64 r0 = 0
0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exit
];
let mut insns = copy_instructions(prog).unwrap();
let mut map_data = MapData {
obj: obj::Map::Legacy(LegacyMap {
def: bpf_map_def {
map_type: bpf_map_type::BPF_MAP_TYPE_ARRAY as u32,
key_size: 4,
value_size: 32,
max_entries: 1,
..Default::default()
},
section_index: 0,
section_kind: BpfSectionKind::Maps,
symbol_index: None,
data: Vec::new(),
}),
fd: None,
pinned: false,
btf_fd: None,
};
if let Ok(map_fd) = map_data.create("aya_global") {
insns[0].imm = map_fd;
let gpl = b"GPL\0";
u.license = gpl.as_ptr() as u64;
u.insn_cnt = insns.len() as u32;
u.insns = insns.as_ptr() as u64;
u.prog_type = bpf_prog_type::BPF_PROG_TYPE_SOCKET_FILTER as u32;
if let Ok(v) = sys_bpf(bpf_cmd::BPF_PROG_LOAD, &attr) {
let fd = v as RawFd;
unsafe { close(fd) };
return true;
}
}
false
}
pub(crate) fn is_btf_supported() -> bool { pub(crate) fn is_btf_supported() -> bool {
let mut btf = Btf::new(); let mut btf = Btf::new();
let name_offset = btf.add_string("int".to_string()); let name_offset = btf.add_string("int".to_string());

Loading…
Cancel
Save