Skip to content

Commit 454c3ca

Browse files
committed
fix: replace panics with proper error handling
This commit addresses several potential panic scenarios by introducing proper error handling.
1 parent 1dfea36 commit 454c3ca

11 files changed

Lines changed: 117 additions & 29 deletions

File tree

aya-obj/src/relocation.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,17 @@ pub enum RelocationError {
8585
/// The relocation number
8686
relocation_number: usize,
8787
},
88+
89+
/// Unsupported relocation
90+
#[error(
91+
"unsupported relocation target: symbol kind `{symbol_kind:?}` at symbol address {address:#x}"
92+
)]
93+
UnsupportedRelocationTarget {
94+
/// The symbol kind
95+
symbol_kind: SymbolKind,
96+
/// The relocation address
97+
address: u64,
98+
},
8899
}
89100

90101
#[derive(Debug, Copy, Clone)]
@@ -392,7 +403,12 @@ impl<'a> FunctionLinker<'a> {
392403
}
393404
// R_BPF_64_64 this is a ld_imm64 text relocation
394405
SymbolKind::Section if rel.size == 64 => sym.address + ins.imm as u64,
395-
_ => todo!(), // FIXME: return an error here,
406+
symbol_kind => {
407+
return Err(RelocationError::UnsupportedRelocationTarget {
408+
symbol_kind,
409+
address: sym.address,
410+
});
411+
}
396412
};
397413
(sym.section_index.unwrap(), address)
398414
} else {

aya/src/maps/info.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,12 @@ impl MapInfo {
118118
pub fn from_pin<P: AsRef<Path>>(path: P) -> Result<Self, MapError> {
119119
use std::os::unix::ffi::OsStrExt as _;
120120

121-
// TODO: avoid this unwrap by adding a new error variant.
122-
let path_string = CString::new(path.as_ref().as_os_str().as_bytes()).unwrap();
121+
let path_string = CString::new(path.as_ref().as_os_str().as_bytes()).map_err(|source| {
122+
MapError::InvalidName {
123+
name: path.as_ref().display().to_string(),
124+
source,
125+
}
126+
})?;
123127
let fd = bpf_get_object(&path_string).map_err(|io_error| SyscallError {
124128
call: "BPF_OBJ_GET",
125129
io_error,

aya/src/maps/mod.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,9 @@ pub enum MapError {
115115
InvalidName {
116116
/// The map name
117117
name: String,
118+
/// source error
119+
#[source]
120+
source: std::ffi::NulError,
118121
},
119122

120123
/// Failed to create map
@@ -575,8 +578,10 @@ impl MapData {
575578
name: &str,
576579
btf_fd: Option<BorrowedFd<'_>>,
577580
) -> Result<Self, MapError> {
578-
let c_name = CString::new(name)
579-
.map_err(|std::ffi::NulError { .. }| MapError::InvalidName { name: name.into() })?;
581+
let c_name = CString::new(name).map_err(|source| MapError::InvalidName {
582+
name: name.into(),
583+
source,
584+
})?;
580585

581586
// BPF_MAP_TYPE_PERF_EVENT_ARRAY's max_entries should not exceed the number of
582587
// CPUs.

aya/src/programs/info.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -220,8 +220,12 @@ impl ProgramInfo {
220220
pub fn from_pin<P: AsRef<Path>>(path: P) -> Result<Self, ProgramError> {
221221
use std::os::unix::ffi::OsStrExt as _;
222222

223-
// TODO: avoid this unwrap by adding a new error variant.
224-
let path_string = CString::new(path.as_ref().as_os_str().as_bytes()).unwrap();
223+
let path_string = CString::new(path.as_ref().as_os_str().as_bytes()).map_err(|source| {
224+
ProgramError::InvalidPath {
225+
path: path.as_ref().display().to_string(),
226+
source,
227+
}
228+
})?;
225229
let fd = bpf_get_object(&path_string).map_err(|io_error| SyscallError {
226230
call: "BPF_OBJ_GET",
227231
io_error,

aya/src/programs/links.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! Program links.
22
use std::{
3-
ffi::CString,
3+
ffi::{CString, NulError},
44
io,
55
os::fd::{AsFd as _, AsRawFd as _, BorrowedFd, RawFd},
66
path::{Path, PathBuf},
@@ -349,8 +349,12 @@ impl PinnedLink {
349349
pub fn from_pin<P: AsRef<Path>>(path: P) -> Result<Self, LinkError> {
350350
use std::os::unix::ffi::OsStrExt as _;
351351

352-
// TODO: avoid this unwrap by adding a new error variant.
353-
let path_string = CString::new(path.as_ref().as_os_str().as_bytes()).unwrap();
352+
let path_string = CString::new(path.as_ref().as_os_str().as_bytes()).map_err(|source| {
353+
LinkError::InvalidPath {
354+
path: path.as_ref().display().to_string(),
355+
source,
356+
}
357+
})?;
354358
let fd = bpf_get_object(&path_string).map_err(|io_error| {
355359
LinkError::SyscallError(SyscallError {
356360
call: "BPF_OBJ_GET",
@@ -594,6 +598,16 @@ pub enum LinkError {
594598
#[error("unknown link type {0}")]
595599
UnknownLinkType(u32),
596600

601+
/// Invalid path.
602+
#[error("invalid path: {path}")]
603+
InvalidPath {
604+
/// path
605+
path: String,
606+
/// source error
607+
#[source]
608+
source: NulError,
609+
},
610+
597611
/// Syscall failed.
598612
#[error(transparent)]
599613
SyscallError(#[from] SyscallError),

aya/src/programs/mod.rs

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ pub mod xdp;
7474

7575
use std::{
7676
borrow::Cow,
77-
ffi::CString,
77+
ffi::{CString, NulError},
7878
io,
7979
os::fd::{AsFd, BorrowedFd},
8080
path::{Path, PathBuf},
@@ -178,6 +178,16 @@ pub enum ProgramError {
178178
name: String,
179179
},
180180

181+
/// The network interface name is invalid.
182+
#[error("invalid network interface name {name}")]
183+
InvalidInterfaceName {
184+
/// interface name
185+
name: String,
186+
/// source error
187+
#[source]
188+
source: NulError,
189+
},
190+
181191
/// The program is not of the expected type.
182192
#[error("unexpected program type")]
183193
UnexpectedProgramType,
@@ -218,11 +228,24 @@ pub enum ProgramError {
218228
#[error(transparent)]
219229
Btf(#[from] BtfError),
220230

221-
/// The program is not attached.
231+
/// The program name is invalid.
222232
#[error("the program name `{name}` is invalid")]
223233
InvalidName {
224234
/// program name
225235
name: String,
236+
/// source error
237+
#[source]
238+
source: NulError,
239+
},
240+
241+
/// The path is invalid.
242+
#[error("the path `{path}` is invalid")]
243+
InvalidPath {
244+
/// path
245+
path: String,
246+
/// source error
247+
#[source]
248+
source: NulError,
226249
},
227250

228251
/// An error occurred while working with IO.
@@ -587,8 +610,12 @@ impl<T: Link> ProgramData<T> {
587610
) -> Result<Self, ProgramError> {
588611
use std::os::unix::ffi::OsStrExt as _;
589612

590-
// TODO: avoid this unwrap by adding a new error variant.
591-
let path_string = CString::new(path.as_ref().as_os_str().as_bytes()).unwrap();
613+
let path_string = CString::new(path.as_ref().as_os_str().as_bytes()).map_err(|source| {
614+
ProgramError::InvalidPath {
615+
path: path.as_ref().display().to_string(),
616+
source,
617+
}
618+
})?;
592619
let fd = bpf_get_object(&path_string).map_err(|io_error| SyscallError {
593620
call: "bpf_obj_get",
594621
io_error,
@@ -685,16 +712,15 @@ fn load_program<T: Link>(
685712
.unwrap_or(0)
686713
});
687714

688-
let prog_name = if let Some(name) = name.as_deref() {
689-
let prog_name = CString::new(name).map_err(|err @ std::ffi::NulError { .. }| {
690-
let name = err.into_vec();
691-
let name = unsafe { String::from_utf8_unchecked(name) };
692-
ProgramError::InvalidName { name }
693-
})?;
694-
Some(prog_name)
695-
} else {
696-
None
697-
};
715+
let prog_name = name
716+
.as_deref()
717+
.map(|name| {
718+
CString::new(name).map_err(|source| {
719+
let name = name.to_owned();
720+
ProgramError::InvalidName { name, source }
721+
})
722+
})
723+
.transpose()?;
698724

699725
let attr = EbpfLoadProgramAttrs {
700726
name: prog_name,

aya/src/programs/raw_trace_point.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,10 @@ impl RawTracePoint {
5151
///
5252
/// The returned value can be used to detach, see [RawTracePoint::detach].
5353
pub fn attach(&mut self, tp_name: &str) -> Result<RawTracePointLinkId, ProgramError> {
54-
let tp_name_c = CString::new(tp_name).unwrap();
54+
let tp_name_c = CString::new(tp_name).map_err(|source| ProgramError::InvalidName {
55+
name: tp_name.to_string(),
56+
source,
57+
})?;
5558
attach_raw_tracepoint(&mut self.data, Some(&tp_name_c))
5659
}
5760
}

aya/src/programs/tc.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -273,8 +273,7 @@ impl SchedClassifier {
273273
match options {
274274
TcAttachOptions::Netlink(options) => {
275275
let name = self.data.name.as_deref().unwrap_or_default();
276-
// TODO: avoid this unwrap by adding a new error variant.
277-
let name = CString::new(name).unwrap();
276+
let name = CString::new(name).map_err(TcError::from)?;
278277
let (priority, handle) = unsafe {
279278
netlink_qdisc_attach(
280279
if_index as i32,

aya/src/programs/xdp.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,11 @@ impl Xdp {
104104
/// When `bpf_link_create` is unavailable or rejects the request, the call
105105
/// transparently falls back to the legacy netlink-based attach path.
106106
pub fn attach(&mut self, interface: &str, flags: XdpFlags) -> Result<XdpLinkId, ProgramError> {
107-
// TODO: avoid this unwrap by adding a new error variant.
108-
let c_interface = CString::new(interface).unwrap();
107+
let c_interface =
108+
CString::new(interface).map_err(|source| ProgramError::InvalidInterfaceName {
109+
name: interface.to_string(),
110+
source,
111+
})?;
109112
let if_index = unsafe { libc::if_nametoindex(c_interface.as_ptr()) };
110113
if if_index == 0 {
111114
return Err(ProgramError::UnknownInterface {

xtask/public-api/aya-obj.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9225,6 +9225,9 @@ pub aya_obj::relocation::RelocationError::UnknownProgram::address: u64
92259225
pub aya_obj::relocation::RelocationError::UnknownProgram::section_index: usize
92269226
pub aya_obj::relocation::RelocationError::UnknownSymbol
92279227
pub aya_obj::relocation::RelocationError::UnknownSymbol::index: usize
9228+
pub aya_obj::relocation::RelocationError::UnsupportedRelocationTarget
9229+
pub aya_obj::relocation::RelocationError::UnsupportedRelocationTarget::address: u64
9230+
pub aya_obj::relocation::RelocationError::UnsupportedRelocationTarget::symbol_kind: object::common::SymbolKind
92289231
impl core::error::Error for aya_obj::relocation::RelocationError
92299232
impl core::fmt::Debug for aya_obj::relocation::RelocationError
92309233
pub fn aya_obj::relocation::RelocationError::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result

0 commit comments

Comments
 (0)