Skip to content

Commit 5722b92

Browse files
committed
Replace unsafe with zerocopy in get_interfaces
1 parent 52ff3d9 commit 5722b92

File tree

3 files changed

+16
-17
lines changed

3 files changed

+16
-17
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ ioctl-sys = "0.8.0"
2121
libc = "0.2.29"
2222
derive_builder = "0.20"
2323
ipnetwork = "0.21.1"
24-
zerocopy = { version = "0.8.27", default-features = false, features = ["derive"] }
24+
zerocopy = { version = "0.8.27", default-features = false, features = ["derive", "alloc"] }
2525

2626
[dev-dependencies]
2727
assert_matches = "1.1.0"

src/lib.rs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@
6060
#![deny(rust_2018_idioms)]
6161

6262
use std::{
63-
ffi::CStr,
63+
ffi::{CStr, c_void},
6464
fmt,
6565
fs::File,
6666
mem,
@@ -531,27 +531,28 @@ impl PfCtl {
531531
// Maximum number of ioctl retries before giving up
532532
const MAX_RETRIES: usize = 2;
533533

534-
let mut buf: Vec<ffi::pfvar::pfi_kif> = Vec::with_capacity(INITIAL_CAPACITY);
535-
let mut iface = unsafe { mem::zeroed::<ffi::pfvar::pfioc_iface>() };
534+
let mut buf: Vec<ffi::pfvar::pfi_kif> =
535+
ffi::pfvar::pfi_kif::new_vec_zeroed(INITIAL_CAPACITY).expect("allocation must succeed");
536+
let mut iface = ffi::pfvar::pfioc_iface::new_zeroed();
536537
interface.try_copy_to(&mut iface.pfiio_name)?;
537538
iface.pfiio_esize = mem::size_of::<ffi::pfvar::pfi_kif>() as i32;
538539

539540
let mut retry = 0;
540541
loop {
541-
iface.pfiio_buffer = buf.as_mut_ptr() as _;
542-
iface.pfiio_size = buf.capacity() as _;
542+
iface.pfiio_buffer = buf.as_mut_ptr().cast::<c_void>();
543+
iface.pfiio_size = buf.len() as i32;
543544

544545
ioctl_guard!(ffi::pf_get_ifaces(self.fd(), &mut iface))?;
545546
let num_system_interfaces = usize::try_from(iface.pfiio_size).unwrap_or_default();
546547

547548
retry += 1;
548549
// Reserve additional space and retry if number of system interfaces exceeds capacity
549-
if retry < MAX_RETRIES && num_system_interfaces > buf.capacity() {
550-
buf.reserve(num_system_interfaces);
550+
if retry < MAX_RETRIES && num_system_interfaces > buf.len() {
551+
buf = ffi::pfvar::pfi_kif::new_vec_zeroed(num_system_interfaces)
552+
.expect("allocation must succeed");
551553
} else {
552-
let new_len = std::cmp::min(num_system_interfaces, buf.capacity());
553-
// SAFETY: safe since new_len is capped at capacity
554-
unsafe { buf.set_len(new_len) };
554+
// truncate will only shorten the vec, but this is fine.
555+
buf.truncate(num_system_interfaces);
555556
break;
556557
}
557558
}

src/rule/interface.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
// option. This file may not be copied, modified, or distributed
77
// except according to those terms.
88

9+
use zerocopy::transmute_ref;
10+
911
use crate::{Error, ErrorInternal, conversion::TryCopyTo};
1012

1113
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -63,12 +65,8 @@ impl TryFrom<crate::ffi::pfvar::pfi_kif> for InterfaceDescription {
6365
type Error = crate::Error;
6466

6567
fn try_from(kif: crate::ffi::pfvar::pfi_kif) -> Result<Self, Self::Error> {
66-
let chars = kif
67-
.pfik_name
68-
.into_iter()
69-
.map(|b| b as u8)
70-
.collect::<Vec<_>>();
71-
let name = std::ffi::CStr::from_bytes_until_nul(&chars)
68+
let pfik_name: &[u8] = transmute_ref!(&kif.pfik_name[..]);
69+
let name = std::ffi::CStr::from_bytes_until_nul(&pfik_name)
7270
.map_err(|_| Error::from(ErrorInternal::InvalidInterfaceName("missing nul byte")))?
7371
.to_str()
7472
.map_err(|_| Error::from(ErrorInternal::InvalidInterfaceName("invalid utf8 encoding")))?

0 commit comments

Comments
 (0)