Skip to content

Commit 5a8a0a4

Browse files
BiomeOS Developercursoragent
andcommitted
deep debt evolution S276: unwrap elimination, sovereign split, memmap2 removal
Production unwrap/expect/unreachable surface eliminated: - sovereign.rs: resp.as_object_mut().unwrap() → if-let guard - mmio_region.rs: NonNull::new().expect() → assert + new_unchecked - dma.rs: Layout expect in Drop → graceful leak-on-error - diagnostic interpreter: pt_ok + 5x expect → if-let destructure - permissions.rs: map.next().expect() → let-else - dispatch/mod.rs: unreachable!() → Option return + error log handler/sovereign.rs (1,003L, 11 handlers) → module directory: - sovereign/init.rs (454L): init, devinit, classify_tier, experiment - sovereign/snapshot.rs (250L): snapshot, compare, catalyst_diff - sovereign/capture.rs (304L): kernel_health, reagent_capture, recipe_replay, runtime_services_probe - sovereign/mod.rs (15L): re-exports memmap2 dependency removed from hw-safe — safe_mmap.rs rewritten to use rustix::mm::mmap/munmap directly (same API used by device_mmap.rs). ExclusivePtr pattern adopted for Send+Sync safety. Stale primal-name type aliases deprecated: - SongbirdNetworkConfigurator → OrchestrationNetworkConfigurator - SongbirdNetworkConfig → OrchestrationNetworkConfig - NestGateResult → StorageServiceResult Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent e275ffd commit 5a8a0a4

16 files changed

Lines changed: 1137 additions & 1091 deletions

File tree

crates/cli/src/network_config/configurator/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ pub struct OrchestrationNetworkConfigurator {
8383
/// Short alias for [`OrchestrationNetworkConfigurator`].
8484
pub type OrchestrationConfigurator = OrchestrationNetworkConfigurator;
8585

86+
#[deprecated(since = "0.2.0", note = "use OrchestrationNetworkConfigurator — capability-based naming")]
8687
/// Legacy alias — prefer [`OrchestrationNetworkConfigurator`].
8788
pub type SongbirdNetworkConfigurator = OrchestrationNetworkConfigurator;
8889

crates/cli/src/network_config/types/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,5 +47,6 @@ pub struct OrchestrationNetworkConfig {
4747
pub health_monitoring: HealthMonitoringConfig,
4848
}
4949

50+
#[deprecated(since = "0.2.0", note = "use OrchestrationNetworkConfig — capability-based naming")]
5051
/// Legacy alias — prefer [`OrchestrationNetworkConfig`].
5152
pub type SongbirdNetworkConfig = OrchestrationNetworkConfig;

crates/core/cylinder/src/mmio_region.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,10 @@ impl MmioRegion {
4848
/// - `len` must match the length passed to `mmap`.
4949
#[must_use]
5050
pub(crate) unsafe fn new(ptr: *mut u8, len: usize) -> Self {
51-
let ptr = NonNull::new(ptr).expect("MmioRegion::new: mmap pointer must be non-null");
51+
assert!(!ptr.is_null(), "MmioRegion::new: mmap pointer must be non-null (caller broke safety contract)");
5252
Self {
53-
ptr,
53+
// SAFETY: asserted non-null above
54+
ptr: unsafe { NonNull::new_unchecked(ptr) },
5455
len,
5556
backing: Backing::Mmap,
5657
}

crates/core/cylinder/src/vfio/channel/diagnostic/interpreter/probe/channel.rs

Lines changed: 12 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -73,25 +73,15 @@ pub fn probe_channel(
7373
let mut pd0 = DmaBuffer::new(container.clone(), 4096, l5_pd0_iova).ok();
7474
let mut pt0 = DmaBuffer::new(container.clone(), 4096, l5_pt0_iova).ok();
7575

76-
let pt_ok = pd3.is_some() && pd2.is_some() && pd1.is_some() && pd0.is_some() && pt0.is_some();
77-
78-
if pt_ok {
76+
if let (Some(pd3), Some(pd2), Some(pd1), Some(pd0), Some(pt0)) =
77+
(&mut pd3, &mut pd2, &mut pd1, &mut pd0, &mut pt0)
78+
{
7979
crate::vfio::channel::page_tables::populate_page_tables_custom(
80-
pd3.as_mut()
81-
.expect("pt_ok guarantees all page table buffers are Some")
82-
.as_mut_slice(),
83-
pd2.as_mut()
84-
.expect("pt_ok guarantees all page table buffers are Some")
85-
.as_mut_slice(),
86-
pd1.as_mut()
87-
.expect("pt_ok guarantees all page table buffers are Some")
88-
.as_mut_slice(),
89-
pd0.as_mut()
90-
.expect("pt_ok guarantees all page table buffers are Some")
91-
.as_mut_slice(),
92-
pt0.as_mut()
93-
.expect("pt_ok guarantees all page table buffers are Some")
94-
.as_mut_slice(),
80+
pd3.as_mut_slice(),
81+
pd2.as_mut_slice(),
82+
pd1.as_mut_slice(),
83+
pd0.as_mut_slice(),
84+
pt0.as_mut_slice(),
9585
l5_pd2_iova,
9686
l5_pd1_iova,
9787
l5_pd0_iova,
@@ -257,11 +247,10 @@ pub fn probe_channel(
257247
crate::vfio::cache_ops::clflush_range(&userd.as_slice()[ramuserd::GP_GET..]);
258248
crate::vfio::cache_ops::memory_fence();
259249
}
260-
let userd_gp_get = u32::from_le_bytes(
261-
userd.as_slice()[ramuserd::GP_GET..ramuserd::GP_GET + 4]
262-
.try_into()
263-
.expect("4-byte slice always fits [u8; 4]"),
264-
);
250+
let gp_get_bytes: [u8; 4] = userd.as_slice()[ramuserd::GP_GET..ramuserd::GP_GET + 4]
251+
.try_into()
252+
.unwrap_or([0; 4]);
253+
let userd_gp_get = u32::from_le_bytes(gp_get_bytes);
265254

266255
let context_loaded = sig != 0xBEEF_0010 && gpbase != 0xBEEF_0048;
267256
let sig_correct = sig == 0x0000_FACE;

crates/core/cylinder/src/vfio/dma.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -347,8 +347,10 @@ impl Drop for DmaBuffer {
347347
let _ = Self::dma_unmap_backend(&self.backend, self.iova, size as u64);
348348

349349
// SAFETY: `size` and `PAGE_SIZE` are identical to those used in new().
350-
let layout = std::alloc::Layout::from_size_align(size, PAGE_SIZE)
351-
.expect("Layout valid: matches alloc in new()");
350+
let Ok(layout) = std::alloc::Layout::from_size_align(size, PAGE_SIZE) else {
351+
tracing::error!(size, PAGE_SIZE, "DMA dealloc layout invalid — leaking buffer to avoid UB");
352+
return;
353+
};
352354
// SAFETY: dealloc matches alloc_zeroed from new(); layout identical.
353355
unsafe { std::alloc::dealloc(ptr, layout) };
354356

crates/core/hw-safe/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ keywords = ["hardware", "mmap", "mmio", "unsafe", "wrapper"]
1313
categories.workspace = true
1414

1515
[dependencies]
16-
memmap2 = "0.9"
1716
rustix = { version = "1", features = ["mm"] }
1817
thiserror = { workspace = true }
1918
tracing = { workspace = true }

crates/core/hw-safe/src/safe_mmap.rs

Lines changed: 82 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,26 @@
11
// SPDX-License-Identifier: AGPL-3.0-or-later
22
#![allow(
33
unsafe_code,
4-
reason = "memmap2 map_raw requires unsafe — containment zone"
4+
reason = "mmap/munmap require unsafe — containment zone"
55
)]
66

77
//! RAII memory-mapped file region.
88
//!
9-
//! [`SafeMmapRegion`] wraps [`memmap2::MmapRaw`] for device BAR files, sysfs
10-
//! resource files, and similar file-backed hardware mappings. The mapping
11-
//! lifetime (munmap on drop) is handled by `memmap2`.
9+
//! [`SafeMmapRegion`] wraps `rustix::mm::mmap`/`munmap` for device BAR files,
10+
//! sysfs resource files, and similar file-backed hardware mappings. The mapping
11+
//! lifetime (munmap on drop) is managed by the RAII struct.
1212
//!
1313
//! This replaces the duplicate mmap patterns in:
1414
//! - `akida-driver` `MmapRegion`
1515
//! - `nvpmu` `Bar0Access`
1616
//! - `display` V4L2 device mappings
1717
1818
use std::fs::File;
19+
use std::os::fd::AsFd;
1920
use std::path::Path;
2021
use std::ptr::NonNull;
2122

22-
use memmap2::{MmapOptions, MmapRaw};
23-
23+
use crate::ExclusivePtr;
2424
use crate::volatile_mmio::VolatileMmio;
2525

2626
/// Error type for mmap operations.
@@ -48,20 +48,26 @@ pub enum MmapError {
4848
/// Underlying I/O error.
4949
source: std::io::Error,
5050
},
51+
/// mmap returned a null pointer.
52+
#[error("mmap returned null for {path}")]
53+
NullPointer {
54+
/// Path with null mmap result.
55+
path: String,
56+
},
5157
}
5258

5359
/// RAII memory-mapped file region.
5460
///
5561
/// Maps a file (typically a PCI BAR resource, sysfs attribute, or device
56-
/// node) into the process address space. Unmaps automatically on drop
57-
/// (handled by [`memmap2`]).
62+
/// node) into the process address space. Unmaps automatically on drop.
5863
///
5964
/// ## Volatile MMIO
6065
///
6166
/// For hardware register access, use [`as_volatile`](SafeMmapRegion::as_volatile)
6267
/// to get a [`VolatileMmio`] view with bounds-checked volatile reads and writes.
6368
pub struct SafeMmapRegion {
64-
mmap: MmapRaw,
69+
ptr: ExclusivePtr,
70+
size: usize,
6571
_file: File,
6672
}
6773

@@ -74,15 +80,32 @@ impl SafeMmapRegion {
7480
/// the mmap syscall fails.
7581
pub fn map_shared_rw(path: &Path) -> Result<Self, MmapError> {
7682
let (file, size) = Self::open_validated(path, true)?;
77-
let mmap = MmapOptions::new()
78-
.len(size)
79-
.map_raw(&file)
80-
.map_err(|source| MmapError::MmapFailed {
81-
path: path.display().to_string(),
82-
source,
83-
})?;
83+
let path_str = path.display().to_string();
84+
85+
// SAFETY: file is a valid open descriptor; size > 0 validated above;
86+
// PROT_READ|PROT_WRITE + MAP_SHARED are correct for device BAR files.
87+
let raw = unsafe {
88+
rustix::mm::mmap(
89+
std::ptr::null_mut(),
90+
size,
91+
rustix::mm::ProtFlags::READ | rustix::mm::ProtFlags::WRITE,
92+
rustix::mm::MapFlags::SHARED,
93+
file.as_fd(),
94+
0,
95+
)
96+
}
97+
.map_err(|e| MmapError::MmapFailed {
98+
path: path_str.clone(),
99+
source: e.into(),
100+
})?;
101+
102+
let ptr = NonNull::new(raw.cast()).ok_or(MmapError::NullPointer { path: path_str })?;
84103
tracing::debug!(path = %path.display(), size, "mmap region created (rw)");
85-
Ok(Self { mmap, _file: file })
104+
Ok(Self {
105+
ptr: ExclusivePtr::new(ptr),
106+
size,
107+
_file: file,
108+
})
86109
}
87110

88111
/// Map a file as a shared read-only memory region.
@@ -93,15 +116,32 @@ impl SafeMmapRegion {
93116
/// the mmap syscall fails.
94117
pub fn map_shared_ro(path: &Path) -> Result<Self, MmapError> {
95118
let (file, size) = Self::open_validated(path, false)?;
96-
let mmap = MmapOptions::new()
97-
.len(size)
98-
.map_raw_read_only(&file)
99-
.map_err(|source| MmapError::MmapFailed {
100-
path: path.display().to_string(),
101-
source,
102-
})?;
119+
let path_str = path.display().to_string();
120+
121+
// SAFETY: file is a valid open descriptor; size > 0 validated above;
122+
// PROT_READ + MAP_SHARED is correct for read-only device mappings.
123+
let raw = unsafe {
124+
rustix::mm::mmap(
125+
std::ptr::null_mut(),
126+
size,
127+
rustix::mm::ProtFlags::READ,
128+
rustix::mm::MapFlags::SHARED,
129+
file.as_fd(),
130+
0,
131+
)
132+
}
133+
.map_err(|e| MmapError::MmapFailed {
134+
path: path_str.clone(),
135+
source: e.into(),
136+
})?;
137+
138+
let ptr = NonNull::new(raw.cast()).ok_or(MmapError::NullPointer { path: path_str })?;
103139
tracing::debug!(path = %path.display(), size, "mmap region created (ro)");
104-
Ok(Self { mmap, _file: file })
140+
Ok(Self {
141+
ptr: ExclusivePtr::new(ptr),
142+
size,
143+
_file: file,
144+
})
105145
}
106146

107147
fn open_validated(path: &Path, writable: bool) -> Result<(File, usize), MmapError> {
@@ -134,53 +174,41 @@ impl SafeMmapRegion {
134174
/// Size of the mapped region in bytes.
135175
#[must_use]
136176
pub fn size(&self) -> usize {
137-
self.mmap.len()
177+
self.size
138178
}
139179

140180
/// Get a [`VolatileMmio`] view for bounds-checked volatile register access.
141181
///
142182
/// The returned view borrows this region — the mapping stays alive.
143-
///
144-
/// # Panics
145-
///
146-
/// Panics if `memmap2` returned a null pointer, which should never happen
147-
/// after a successful `map_raw` call.
148183
#[must_use]
149184
pub fn as_volatile(&self) -> VolatileMmio<'_> {
150-
debug_assert!(
151-
self.mmap.len() > 0,
152-
"SafeMmapRegion invariant: non-empty mapping (see open_validated)"
153-
);
154-
// SAFETY: mmap is valid (from a successful map_raw call). as_mut_ptr
155-
// returns a valid pointer for len() bytes. The VolatileMmio borrows
156-
// self, preventing use-after-unmap.
157-
unsafe {
158-
VolatileMmio::new(
159-
NonNull::new(self.mmap.as_mut_ptr())
160-
.expect("memmap2 returned null — mapping was successful"),
161-
self.mmap.len(),
162-
)
163-
}
185+
// SAFETY: ptr is valid for `size` bytes from the successful mmap.
186+
// The VolatileMmio borrows self, preventing use-after-unmap.
187+
unsafe { VolatileMmio::new(self.ptr.as_non_null(), self.size) }
164188
}
165189

166190
/// Raw pointer to the mapped region. Use [`as_volatile`](Self::as_volatile)
167191
/// for safe register access instead.
168-
///
169-
/// # Panics
170-
///
171-
/// Panics if `memmap2` returned a null pointer, which should never happen
172-
/// after a successful `map_raw` call.
173192
#[must_use]
174193
pub fn as_ptr(&self) -> NonNull<u8> {
175-
NonNull::new(self.mmap.as_mut_ptr())
176-
.expect("memmap2 returned null — mapping was successful")
194+
self.ptr.as_non_null()
195+
}
196+
}
197+
198+
impl Drop for SafeMmapRegion {
199+
fn drop(&mut self) {
200+
// SAFETY: ptr and size from a successful mmap in constructor;
201+
// Drop runs exactly once; no outstanding borrows possible.
202+
unsafe {
203+
let _ = rustix::mm::munmap(self.ptr.as_ptr().cast(), self.size);
204+
}
177205
}
178206
}
179207

180208
impl std::fmt::Debug for SafeMmapRegion {
181209
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
182210
f.debug_struct("SafeMmapRegion")
183-
.field("size", &self.mmap.len())
211+
.field("size", &self.size)
184212
.finish_non_exhaustive()
185213
}
186214
}
@@ -238,7 +266,7 @@ mod tests {
238266

239267
assert!(mmio.read_u32(0).is_ok());
240268
assert!(mmio.read_u32(4).is_ok());
241-
assert!(mmio.read_u32(8).is_err()); // out of bounds
269+
assert!(mmio.read_u32(8).is_err());
242270
}
243271

244272
#[test]

crates/core/toadstool/src/biomeos_integration/auth/permissions.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,9 @@ impl<'de> Deserialize<'de> for PrimalTypeConfig {
125125
map.len()
126126
)));
127127
}
128-
let (k, v) = map.into_iter().next().expect("len checked");
128+
let Some((k, v)) = map.into_iter().next() else {
129+
return Err(D::Error::custom("empty manifest map after len check"));
130+
};
129131
match k.as_str() {
130132
manifest_serde::TOADSTOOL => ToadStoolConfig::deserialize(v)
131133
.map(Self::ToadStool)

crates/integration/storage/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ pub mod types;
5151
mod utils;
5252

5353
// Re-export core types and functionality
54+
#[allow(deprecated, reason = "re-exporting deprecated NestGateResult for backward compatibility")]
5455
pub use types::{
5556
ArtifactFilters, ArtifactMetadata, ArtifactType, CachedArtifact, CompressionType,
5657
EncryptionType, NestGateResult, StorageError, StorageInfo, StorageServiceResult, StorageTier,

crates/integration/storage/src/types.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ pub enum StorageError {
4949
/// Result type for storage-service operations.
5050
pub type StorageServiceResult<T> = Result<T, StorageError>;
5151

52+
#[deprecated(since = "0.2.0", note = "use StorageServiceResult — capability-based naming")]
5253
/// Legacy alias for [`StorageServiceResult`].
5354
pub type NestGateResult<T> = StorageServiceResult<T>;
5455

0 commit comments

Comments
 (0)