瀏覽代碼

fix(aya): Fill bss maps with zeros

The loader should fill bss maps with zeros according to the size of the
ELF section.
Failure to do so yields weird verifier messages as follows:

```
cannot access ptr member ops with moff 0 in struct bpf_map with off 0 size 4
```

Reference to this in the cilium/ebpf code is here [1].
I could not find a reference in libbpf.

1: https://github.com/cilium/ebpf/blob/d0c8fc19376a9276cf5310c288d1eae99ed39eb3/elf_reader.go#L1159-L1165

Signed-off-by: Dave Tucker <[email protected]>
Dave Tucker 4 月之前
父節點
當前提交
ca0c32d107
共有 2 個文件被更改,包括 14 次插入2 次删除
  1. 13 1
      aya-obj/src/obj.rs
  2. 1 1
      aya/src/maps/mod.rs

+ 13 - 1
aya-obj/src/obj.rs

@@ -5,6 +5,7 @@ use alloc::{
     collections::BTreeMap,
     ffi::CString,
     string::{String, ToString},
+    vec,
     vec::Vec,
 };
 use core::{ffi::CStr, mem, ptr, slice::from_raw_parts_mut, str::FromStr};
@@ -1193,7 +1194,7 @@ fn get_map_field(btf: &Btf, type_id: u32) -> Result<u32, BtfError> {
 // bytes and are relocated based on their section index.
 fn parse_data_map_section(section: &Section) -> Result<Map, ParseError> {
     let (def, data) = match section.kind {
-        EbpfSectionKind::Bss | EbpfSectionKind::Data | EbpfSectionKind::Rodata => {
+        EbpfSectionKind::Data | EbpfSectionKind::Rodata => {
             let def = bpf_map_def {
                 map_type: BPF_MAP_TYPE_ARRAY as u32,
                 key_size: mem::size_of::<u32>() as u32,
@@ -1210,6 +1211,17 @@ fn parse_data_map_section(section: &Section) -> Result<Map, ParseError> {
             };
             (def, section.data.to_vec())
         }
+        EbpfSectionKind::Bss => {
+            let def = bpf_map_def {
+                map_type: BPF_MAP_TYPE_ARRAY as u32,
+                key_size: mem::size_of::<u32>() as u32,
+                value_size: section.size as u32,
+                max_entries: 1,
+                map_flags: 0,
+                ..Default::default()
+            };
+            (def, vec![0; section.size as usize])
+        }
         _ => unreachable!(),
     };
     Ok(Map::Legacy(LegacyMap {

+ 1 - 1
aya/src/maps/mod.rs

@@ -637,7 +637,7 @@ impl MapData {
 
     pub(crate) fn finalize(&mut self) -> Result<(), MapError> {
         let Self { obj, fd } = self;
-        if !obj.data().is_empty() && obj.section_kind() != EbpfSectionKind::Bss {
+        if !obj.data().is_empty() {
             bpf_map_update_elem_ptr(fd.as_fd(), &0 as *const _, obj.data_mut().as_mut_ptr(), 0)
                 .map_err(|(_, io_error)| SyscallError {
                     call: "bpf_map_update_elem",