Skip to content

Commit

Permalink
Merge branch 'aya-rs:main' into lsm_sleepable
Browse files Browse the repository at this point in the history
  • Loading branch information
epompeii committed Apr 25, 2023
2 parents 85714d5 + fce1d76 commit 1f2006b
Show file tree
Hide file tree
Showing 41 changed files with 1,222 additions and 851 deletions.
5 changes: 1 addition & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@ panic = "abort"
[profile.release]
panic = "abort"

[profile.dev.package.integration-ebpf]
opt-level = 2
overflow-checks = false

[profile.release.package.integration-ebpf]
debug = 2
codegen-units = 1
2 changes: 1 addition & 1 deletion aya-log-common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ userspace = [ "aya" ]

[dependencies]
aya = { path = "../aya", version = "0.11.0", optional=true }
num_enum = { version = "0.5", default-features = false }
num_enum = { version = "0.6", default-features = false }

[lib]
path = "src/lib.rs"
124 changes: 104 additions & 20 deletions aya-obj/src/btf/btf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,19 @@ impl Btf {
// Sanitize DATASEC if they are not supported
BtfType::DataSec(d) if !features.btf_datasec => {
debug!("{}: not supported. replacing with STRUCT", kind);

// STRUCT aren't allowed to have "." in their name, fixup this if needed.
let mut name_offset = t.name_offset();
let sec_name = self.string_at(name_offset)?;
let name = sec_name.to_string();

// Handle any "." characters in struct names
// Example: ".maps"
let fixed_name = name.replace('.', "_");
if fixed_name != name {
name_offset = self.add_string(fixed_name);
}

let mut members = vec![];
for member in d.entries.iter() {
let mt = types.type_by_id(member.btf_type).unwrap();
Expand All @@ -441,7 +454,9 @@ impl Btf {
offset: member.offset * 8,
})
}
types.types[i] = BtfType::Struct(Struct::new(t.name_offset(), members, 0));

types.types[i] =
BtfType::Struct(Struct::new(name_offset, members, d.entries.len() as u32));
}
// Fixup DATASEC
// DATASEC sizes aren't always set by LLVM
Expand Down Expand Up @@ -536,22 +551,39 @@ impl Btf {
types.types[i] = enum_type;
}
// Sanitize FUNC
BtfType::Func(ty) if !features.btf_func => {
debug!("{}: not supported. replacing with TYPEDEF", kind);
let typedef_type = BtfType::Typedef(Typedef::new(ty.name_offset, ty.btf_type));
types.types[i] = typedef_type;
}
// Sanitize BTF_FUNC_GLOBAL
BtfType::Func(ty) if !features.btf_func_global => {
let mut fixed_ty = ty.clone();
if ty.linkage() == FuncLinkage::Global {
debug!(
"{}: BTF_FUNC_GLOBAL not supported. replacing with BTF_FUNC_STATIC",
kind
);
fixed_ty.set_linkage(FuncLinkage::Static);
BtfType::Func(ty) => {
let name = self.string_at(ty.name_offset)?;
// Sanitize FUNC
if !features.btf_func {
debug!("{}: not supported. replacing with TYPEDEF", kind);
let typedef_type =
BtfType::Typedef(Typedef::new(ty.name_offset, ty.btf_type));
types.types[i] = typedef_type;
} else if !features.btf_func_global
|| name == "memset"
|| name == "memcpy"
|| name == "memmove"
|| name == "memcmp"
{
// Sanitize BTF_FUNC_GLOBAL when not supported and ensure that
// memory builtins are marked as static. Globals are type checked
// and verified separately from their callers, while instead we
// want tracking info (eg bound checks) to be propagated to the
// memory builtins.
let mut fixed_ty = ty.clone();
if ty.linkage() == FuncLinkage::Global {
if !features.btf_func_global {
debug!(
"{}: BTF_FUNC_GLOBAL not supported. replacing with BTF_FUNC_STATIC",
kind
);
} else {
debug!("changing FUNC {name} linkage to BTF_FUNC_STATIC");
}
fixed_ty.set_linkage(FuncLinkage::Static);
}
types.types[i] = BtfType::Func(fixed_ty);
}
types.types[i] = BtfType::Func(fixed_ty);
}
// Sanitize FLOAT
BtfType::Float(ty) if !features.btf_float => {
Expand Down Expand Up @@ -1045,9 +1077,7 @@ mod tests {
let name_offset = btf.add_string("&mut int".to_string());
let ptr_type_id = btf.add_type(BtfType::Ptr(Ptr::new(name_offset, int_type_id)));

let features = BtfFeatures {
..Default::default()
};
let features = Default::default();

btf.fixup_and_sanitize(&HashMap::new(), &HashMap::new(), &features)
.unwrap();
Expand Down Expand Up @@ -1118,7 +1148,7 @@ mod tests {
VarLinkage::Static,
)));

let name_offset = btf.add_string(".data".to_string());
let name_offset = btf.add_string("data".to_string());
let variables = vec![DataSecEntry {
btf_type: var_type_id,
offset: 0,
Expand Down Expand Up @@ -1352,6 +1382,60 @@ mod tests {
Btf::parse(&raw, Endianness::default()).unwrap();
}

#[test]
fn test_sanitize_mem_builtins() {
let mut btf = Btf::new();
let name_offset = btf.add_string("int".to_string());
let int_type_id = btf.add_type(BtfType::Int(Int::new(
name_offset,
4,
IntEncoding::Signed,
0,
)));

let params = vec![
BtfParam {
name_offset: btf.add_string("a".to_string()),
btf_type: int_type_id,
},
BtfParam {
name_offset: btf.add_string("b".to_string()),
btf_type: int_type_id,
},
];
let func_proto_type_id =
btf.add_type(BtfType::FuncProto(FuncProto::new(params, int_type_id)));

let builtins = ["memset", "memcpy", "memcmp", "memmove"];
for fname in builtins {
let func_name_offset = btf.add_string(fname.to_string());
let func_type_id = btf.add_type(BtfType::Func(Func::new(
func_name_offset,
func_proto_type_id,
FuncLinkage::Global,
)));

let features = BtfFeatures {
btf_func: true,
btf_func_global: true, // to force function name check
..Default::default()
};

btf.fixup_and_sanitize(&HashMap::new(), &HashMap::new(), &features)
.unwrap();

if let BtfType::Func(fixed) = btf.type_by_id(func_type_id).unwrap() {
assert!(fixed.linkage() == FuncLinkage::Static);
} else {
panic!("not a func")
}

// Ensure we can convert to bytes and back again
let raw = btf.to_bytes();
Btf::parse(&raw, Endianness::default()).unwrap();
}
}

#[test]
fn test_sanitize_float() {
let mut btf = Btf::new();
Expand Down
5 changes: 3 additions & 2 deletions aya-obj/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,9 @@
//! let bytes = std::fs::read("program.o").unwrap();
//! let mut object = Object::parse(&bytes).unwrap();
//! // Relocate the programs
//! object.relocate_calls().unwrap();
//! object.relocate_maps(std::iter::empty()).unwrap();
//! let text_sections = std::collections::HashSet::new();
//! object.relocate_calls(&text_sections).unwrap();
//! object.relocate_maps(std::iter::empty(), &text_sections).unwrap();
//!
//! // Run with rbpf
//! let instructions = &object.programs["prog_name"].function.instructions;
Expand Down
70 changes: 26 additions & 44 deletions aya-obj/src/maps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@

use core::mem;

use crate::thiserror::{self, Error};
use crate::{
thiserror::{self, Error},
BpfSectionKind,
};
use alloc::vec::Vec;

/// Invalid map type encontered
Expand Down Expand Up @@ -139,33 +142,6 @@ pub struct bpf_map_def {
/// The first five __u32 of `bpf_map_def` must be defined.
pub(crate) const MINIMUM_MAP_SIZE: usize = mem::size_of::<u32>() * 5;

/// Kinds of maps
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum MapKind {
/// A map holding `.bss` section data
Bss,
/// A map holding `.data` section data
Data,
/// A map holding `.rodata` section data
Rodata,
/// Other maps
Other,
}

impl From<&str> for MapKind {
fn from(s: &str) -> Self {
if s == ".bss" {
MapKind::Bss
} else if s.starts_with(".data") {
MapKind::Data
} else if s.starts_with(".rodata") {
MapKind::Rodata
} else {
MapKind::Other
}
}
}

/// Map data defined in `maps` or `.maps` sections
#[derive(Debug, Clone)]
pub enum Map {
Expand Down Expand Up @@ -248,14 +224,6 @@ impl Map {
}
}

/// Returns the map kind
pub fn kind(&self) -> MapKind {
match self {
Map::Legacy(m) => m.kind,
Map::Btf(m) => m.kind,
}
}

/// Returns the section index
pub fn section_index(&self) -> usize {
match self {
Expand All @@ -264,11 +232,22 @@ impl Map {
}
}

/// Returns the symbol index
pub fn symbol_index(&self) -> usize {
/// Returns the section kind.
pub fn section_kind(&self) -> BpfSectionKind {
match self {
Map::Legacy(m) => m.section_kind,
Map::Btf(_) => BpfSectionKind::BtfMaps,
}
}

/// Returns the symbol index.
///
/// This is `None` for data maps (.bss, .data and .rodata) since those don't
/// need symbols in order to be relocated.
pub fn symbol_index(&self) -> Option<usize> {
match self {
Map::Legacy(m) => m.symbol_index,
Map::Btf(m) => m.symbol_index,
Map::Btf(m) => Some(m.symbol_index),
}
}
}
Expand All @@ -283,12 +262,16 @@ pub struct LegacyMap {
pub def: bpf_map_def,
/// The section index
pub section_index: usize,
/// The symbol index
pub symbol_index: usize,
/// The section kind
pub section_kind: BpfSectionKind,
/// The symbol index.
///
/// This is None for data maps (.bss .data and .rodata). We don't need
/// symbols to relocate those since they don't contain multiple maps, but
/// are just a flat array of bytes.
pub symbol_index: Option<usize>,
/// The map data
pub data: Vec<u8>,
/// The map kind
pub kind: MapKind,
}

/// A BTF-defined map, most likely from a `.maps` section.
Expand All @@ -298,6 +281,5 @@ pub struct BtfMap {
pub def: BtfMapDef,
pub(crate) section_index: usize,
pub(crate) symbol_index: usize,
pub(crate) kind: MapKind,
pub(crate) data: Vec<u8>,
}
Loading

0 comments on commit 1f2006b

Please sign in to comment.