From 9b21c85a6ff16c24bce096ff0814cc313725c509 Mon Sep 17 00:00:00 2001 From: aorhant <aorhant@scaleway.com> Date: Wed, 26 Feb 2025 18:54:13 +0100 Subject: [PATCH] feat(aya): return correct Option from bpf_map_lookup_elem_per_cpu bpf_map_lookup_elem_per_cpu doesn't check the Option inside the Result:Ok, thus when it receive a Ok(None), it returns a zeroed value PerCpuValues. --- aya/src/maps/hash_map/per_cpu_hash_map.rs | 25 ++++++++++++++++++++++- aya/src/sys/bpf.rs | 2 +- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/aya/src/maps/hash_map/per_cpu_hash_map.rs b/aya/src/maps/hash_map/per_cpu_hash_map.rs index d9194668..3d402a8b 100644 --- a/aya/src/maps/hash_map/per_cpu_hash_map.rs +++ b/aya/src/maps/hash_map/per_cpu_hash_map.rs @@ -151,12 +151,23 @@ impl<T: Borrow<MapData>, K: Pod, V: Pod> IterableMap<K, PerCpuValues<V>> #[cfg(test)] mod tests { + use std::{ffi::c_long, io}; + + use assert_matches::assert_matches; use aya_obj::generated::bpf_map_type::{ BPF_MAP_TYPE_LRU_PERCPU_HASH, BPF_MAP_TYPE_PERCPU_HASH, }; + use libc::ENOENT; use super::*; - use crate::maps::{test_utils, Map}; + use crate::{ + maps::{test_utils, Map}, + sys::{override_syscall, SysResult}, + }; + + fn sys_error(value: i32) -> SysResult<c_long> { + Err((-1, io::Error::from_raw_os_error(value))) + } #[test] fn test_try_from_ok() { @@ -174,4 +185,16 @@ mod tests { let map = Map::PerCpuLruHashMap(map_data()); assert!(PerCpuHashMap::<_, u32, u32>::try_from(&map).is_ok()) } + #[test] + #[cfg_attr(miri, ignore = "`open` not available when isolation is enabled")] + fn test_get_not_found() { + let map_data = + || test_utils::new_map(test_utils::new_obj_map::<u32>(BPF_MAP_TYPE_LRU_PERCPU_HASH)); + let map = Map::PerCpuHashMap(map_data()); + let map = PerCpuHashMap::<_, u32, u32>::try_from(&map).unwrap(); + + override_syscall(|_| sys_error(ENOENT)); + + assert_matches!(map.get(&1, 0), Err(MapError::KeyNotFound)); + } } diff --git a/aya/src/sys/bpf.rs b/aya/src/sys/bpf.rs index 791959f1..51ca7a97 100644 --- a/aya/src/sys/bpf.rs +++ b/aya/src/sys/bpf.rs @@ -249,7 +249,7 @@ pub(crate) fn bpf_map_lookup_elem_per_cpu<K: Pod, V: Pod>( ) -> SysResult<Option<PerCpuValues<V>>> { let mut mem = PerCpuValues::<V>::alloc_kernel_mem().map_err(|io_error| (-1, io_error))?; match bpf_map_lookup_elem_ptr(fd, Some(key), mem.as_mut_ptr(), flags) { - Ok(_) => Ok(Some(unsafe { PerCpuValues::from_kernel_mem(mem) })), + Ok(v) => Ok(v.map(|()| unsafe { PerCpuValues::from_kernel_mem(mem) })), Err((_, io_error)) if io_error.raw_os_error() == Some(ENOENT) => Ok(None), Err(e) => Err(e), }