Merge pull request #1073 from dave-tucker/reloc-bug

fix(aya): BSS Sections must be filled with zeros
pull/1074/head
Dave Tucker 3 months ago committed by GitHub
commit b2ac9fe85d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -5,6 +5,7 @@ use alloc::{
collections::BTreeMap, collections::BTreeMap,
ffi::CString, ffi::CString,
string::{String, ToString}, string::{String, ToString},
vec,
vec::Vec, vec::Vec,
}; };
use core::{ffi::CStr, mem, ptr, slice::from_raw_parts_mut, str::FromStr}; 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. // bytes and are relocated based on their section index.
fn parse_data_map_section(section: &Section) -> Result<Map, ParseError> { fn parse_data_map_section(section: &Section) -> Result<Map, ParseError> {
let (def, data) = match section.kind { let (def, data) = match section.kind {
EbpfSectionKind::Bss | EbpfSectionKind::Data | EbpfSectionKind::Rodata => { EbpfSectionKind::Data | EbpfSectionKind::Rodata => {
let def = bpf_map_def { let def = bpf_map_def {
map_type: BPF_MAP_TYPE_ARRAY as u32, map_type: BPF_MAP_TYPE_ARRAY as u32,
key_size: mem::size_of::<u32>() 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()) (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!(), _ => unreachable!(),
}; };
Ok(Map::Legacy(LegacyMap { Ok(Map::Legacy(LegacyMap {

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

@ -128,6 +128,7 @@ fn run() -> anyhow::Result<()> {
let path = entry.path(); let path = entry.path();
let status = std::process::Command::new(&path) let status = std::process::Command::new(&path)
.args(&args) .args(&args)
.env("RUST_LOG", "debug")
.status() .status()
.with_context(|| format!("failed to execute {}", path.display()))?; .with_context(|| format!("failed to execute {}", path.display()))?;

@ -0,0 +1,21 @@
// clang-format off
#include <vmlinux.h>
#include <bpf/bpf_helpers.h>
// clang-format on
volatile unsigned int key1 = 0; // .bss
volatile unsigned int key2 = 1; // .data
volatile const unsigned int key3 = 2; // .rodata
SEC("xdp")
int variables_reloc(struct xdp_md *ctx) {
if (key1 == 0 && key2 != 1 && key3 != 2) {
key1 += 1;
key2 += 1;
return XDP_DROP;
} else {
return XDP_PASS;
}
}
char _license[] SEC("license") = "GPL";

@ -71,6 +71,7 @@ fn main() {
("multimap-btf.bpf.c", false), ("multimap-btf.bpf.c", false),
("reloc.bpf.c", true), ("reloc.bpf.c", true),
("text_64_64_reloc.c", false), ("text_64_64_reloc.c", false),
("variables_reloc.bpf.c", false),
]; ];
if build_integration_bpf { if build_integration_bpf {

@ -9,6 +9,8 @@ pub const RELOC_BTF: &[u8] =
include_bytes_aligned!(concat!(env!("OUT_DIR"), "/reloc.bpf.target.o")); include_bytes_aligned!(concat!(env!("OUT_DIR"), "/reloc.bpf.target.o"));
pub const TEXT_64_64_RELOC: &[u8] = pub const TEXT_64_64_RELOC: &[u8] =
include_bytes_aligned!(concat!(env!("OUT_DIR"), "/text_64_64_reloc.o")); include_bytes_aligned!(concat!(env!("OUT_DIR"), "/text_64_64_reloc.o"));
pub const VARIABLES_RELOC: &[u8] =
include_bytes_aligned!(concat!(env!("OUT_DIR"), "/variables_reloc.bpf.o"));
pub const LOG: &[u8] = include_bytes_aligned!(concat!(env!("OUT_DIR"), "/log")); pub const LOG: &[u8] = include_bytes_aligned!(concat!(env!("OUT_DIR"), "/log"));
pub const MAP_TEST: &[u8] = include_bytes_aligned!(concat!(env!("OUT_DIR"), "/map_test")); pub const MAP_TEST: &[u8] = include_bytes_aligned!(concat!(env!("OUT_DIR"), "/map_test"));

@ -1,4 +1,8 @@
use aya::{programs::UProbe, util::KernelVersion, Ebpf}; use aya::{
programs::{UProbe, Xdp},
util::KernelVersion,
Ebpf,
};
use test_log::test; use test_log::test;
#[test] #[test]
@ -33,6 +37,17 @@ fn text_64_64_reloc() {
assert_eq!(m.get(&1, 0).unwrap(), 3); assert_eq!(m.get(&1, 0).unwrap(), 3);
} }
#[test]
fn variables_reloc() {
let mut bpf = Ebpf::load(crate::VARIABLES_RELOC).unwrap();
let prog: &mut Xdp = bpf
.program_mut("variables_reloc")
.unwrap()
.try_into()
.unwrap();
prog.load().unwrap();
}
fn load_and_attach(name: &str, bytes: &[u8]) -> Ebpf { fn load_and_attach(name: &str, bytes: &[u8]) -> Ebpf {
let mut bpf = Ebpf::load(bytes).unwrap(); let mut bpf = Ebpf::load(bytes).unwrap();

Loading…
Cancel
Save