Browse Source

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 months ago
parent
commit
ca0c32d107
2 changed files with 14 additions and 2 deletions
  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",