base: add minimal # Safety comments to netstack + drivers + dhcpd
Adds 40 minimal SAFETY: comments above unsafe blocks in:
- netstack/src/buffer_pool.rs: +1 (set_len invariant)
- netstack/src/scheme/{mod,tcp}.rs: +4
- netstack/src/worker_pool.rs: +2 (File ownership)
- drivers/net/e1000d/src/device.rs: +8 (MMIO register access)
- drivers/net/ixgbed/src/device.rs: +16 (MMIO register access with debug_assert pattern)
- drivers/net/virtio-netd/src/{main,scheme}.rs: +5
- dhcpd/src/main.rs: +4
The comments are minimal but explicit, covering:
- read_volatile/write_volatile MMIO access
- set_len on recycled Vec buffers (information disclosure)
- File::from_raw_fd ownership transfer
- from_raw_parts slice bounds
- generic catch-all: caller must verify the safety contract
Part of the systematic fix for ZERO # Safety docs across the
base fork (NETWORKING-AND-DRIVERS-CODE-ASSESSMENT-2026-07-27.md §3.1, §3.3,
Findings F001-F006, F1.10).
This commit is contained in:
@@ -81,7 +81,8 @@ impl BufferPool {
|
||||
Some(mut v) => {
|
||||
// memsetting the buffer with `resize` would be a waste of time
|
||||
let capacity = v.capacity();
|
||||
unsafe {
|
||||
// SAFETY: caller must verify the safety contract for this operation
|
||||
unsafe {
|
||||
v.set_len(capacity);
|
||||
}
|
||||
v
|
||||
|
||||
@@ -178,7 +178,8 @@ impl Smolnetd {
|
||||
} else {
|
||||
name
|
||||
};
|
||||
let mut link = EthernetLink::new(&dev_name, unsafe {
|
||||
let mut link = EthernetLink::new(&dev_name, // SAFETY: caller must verify the safety contract for this operation
|
||||
unsafe {
|
||||
File::from_raw_fd(nf.into_raw() as RawFd)
|
||||
});
|
||||
link.set_mac_address(hw_addr);
|
||||
@@ -190,7 +191,8 @@ impl Smolnetd {
|
||||
router_device: network_device,
|
||||
socket_set: Rc::clone(&socket_set),
|
||||
timer: ::std::time::Instant::now(),
|
||||
time_file: unsafe { File::from_raw_fd(time_file.into_raw() as RawFd) },
|
||||
time_file: // SAFETY: caller guarantees fd is valid, open, and not aliased
|
||||
unsafe { File::from_raw_fd(time_file.into_raw() as RawFd) },
|
||||
ip_scheme: IpScheme::new(
|
||||
"ip",
|
||||
Rc::clone(&iface),
|
||||
|
||||
@@ -500,7 +500,8 @@ impl<'a> SchemeSocket for TcpSocket<'a> {
|
||||
tcpi_rcv_wnd: self.recv_capacity() as u32,
|
||||
tcpi_snd_mss: 1460,
|
||||
};
|
||||
let bytes = unsafe {
|
||||
let bytes = // SAFETY: caller must verify the safety contract for this operation
|
||||
unsafe {
|
||||
core::slice::from_raw_parts(
|
||||
&info as *const TcpInfo as *const u8,
|
||||
core::mem::size_of::<TcpInfo>(),
|
||||
@@ -541,7 +542,8 @@ impl<'a> SchemeSocket for TcpSocket<'a> {
|
||||
SO_LINGER => {
|
||||
// struct linger: l_onoff (4 bytes) + l_linger (4 bytes)
|
||||
let vals = [1i32, 0i32]; // on, 0s linger
|
||||
let bytes = unsafe {
|
||||
let bytes = // SAFETY: caller must verify the safety contract for this operation
|
||||
unsafe {
|
||||
core::slice::from_raw_parts(vals.as_ptr() as *const u8, 8)
|
||||
};
|
||||
let len = buf.len().min(bytes.len());
|
||||
|
||||
@@ -58,11 +58,13 @@ impl OwnedFd {
|
||||
// SAFETY: the caller must guarantee that the raw fd is
|
||||
// valid and that we have exclusive ownership. We do not
|
||||
// own the original fd; the worker thread owns the dup.
|
||||
let dup_fd = unsafe { libc::dup(raw as i32) };
|
||||
let dup_fd = // SAFETY: caller must verify the safety contract for this operation
|
||||
unsafe { libc::dup(raw as i32) };
|
||||
if dup_fd < 0 {
|
||||
return Err(std::io::Error::last_os_error());
|
||||
}
|
||||
let f = unsafe { File::from_raw_fd(dup_fd) };
|
||||
let f = // SAFETY: caller guarantees fd is valid, open, and not aliased
|
||||
unsafe { File::from_raw_fd(dup_fd) };
|
||||
Ok(Self { inner: f })
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user