Skip to content

Commit

Permalink
aya: Do not create data maps on kernel without global data support
Browse files Browse the repository at this point in the history
Fix map creation failure when a BPF have a data section on older
kernel. (< 5.2)

If the BPF uses that section, relocation will fail accordingly and
report an error.
  • Loading branch information
marysaka committed May 10, 2023
1 parent 7d88470 commit 591e212
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 5 deletions.
1 change: 1 addition & 0 deletions aya-obj/src/obj.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ pub struct Features {
pub bpf_name: bool,
pub bpf_probe_read_kernel: bool,
pub bpf_perf_link: bool,
pub bpf_global_data: bool,
pub btf: Option<BtfFeatures>,
}

Expand Down
16 changes: 12 additions & 4 deletions aya/src/bpf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,11 @@ use crate::{
SkMsg, SkSkb, SkSkbKind, SockOps, SocketFilter, TracePoint, UProbe, Xdp,
},
sys::{
bpf_load_btf, bpf_map_freeze, bpf_map_update_elem_ptr, is_btf_datasec_supported,
is_btf_decl_tag_supported, is_btf_float_supported, is_btf_func_global_supported,
is_btf_func_supported, is_btf_supported, is_btf_type_tag_supported, is_perf_link_supported,
is_probe_read_kernel_supported, is_prog_name_supported, retry_with_verifier_logs,
bpf_load_btf, bpf_map_freeze, bpf_map_update_elem_ptr, is_bpf_global_data_supported,
is_btf_datasec_supported, is_btf_decl_tag_supported, is_btf_float_supported,
is_btf_func_global_supported, is_btf_func_supported, is_btf_supported,
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},
};
Expand Down Expand Up @@ -86,6 +87,7 @@ fn detect_features() -> Features {
bpf_name: is_prog_name_supported(),
bpf_probe_read_kernel: is_probe_read_kernel_supported(),
bpf_perf_link: is_perf_link_supported(),
bpf_global_data: is_bpf_global_data_supported(),
btf,
};
debug!("BPF Feature Detection: {:#?}", f);
Expand Down Expand Up @@ -358,6 +360,12 @@ impl<'a> BpfLoader<'a> {
}
let mut maps = HashMap::new();
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()) {
Some(size) => obj.set_max_entries(*size),
None => {
Expand Down
60 changes: 59 additions & 1 deletion aya/src/sys/bpf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,17 @@ use std::{
};

use libc::{c_char, c_long, close, ENOENT, ENOSPC};
use obj::{
maps::{bpf_map_def, LegacyMap},
BpfSectionKind,
};

use crate::{
generated::{
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,
},
maps::PerCpuValues,
maps::{MapData, PerCpuValues},
obj::{
self,
btf::{
Expand Down Expand Up @@ -661,6 +665,60 @@ pub(crate) fn is_perf_link_supported() -> bool {
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 {
let mut btf = Btf::new();
let name_offset = btf.add_string("int".to_string());
Expand Down

0 comments on commit 591e212

Please sign in to comment.