From f32461a336cca5d9ab6ccf0a30d95d544fc8cf08 Mon Sep 17 00:00:00 2001 From: Thomas de Zeeuw Date: Wed, 28 Jul 2021 18:32:54 +0200 Subject: [PATCH] Assert validity on the raw socket in SockRef::from Since we now use the niche feature on Unix it's unsound to use SockRef::from(-1), but it can be done without any unsafe. This change adds an assertion to ensure we hit this soundness issue. Still need to wait on the I/O safety RFC: https://github.com/rust-lang/rfcs/blob/master/text/3128-io-safety.md Tracking issue: https://github.com/rust-lang/rust/issues/87074 Implementation pr: https://github.com/rust-lang/rust/pull/87329 --- src/sockref.rs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/sockref.rs b/src/sockref.rs index f5807d80..1c8c823c 100644 --- a/src/sockref.rs +++ b/src/sockref.rs @@ -109,8 +109,10 @@ where { /// The caller must ensure `S` is actually a socket. fn from(socket: &'s S) -> Self { + let fd = socket.as_raw_fd(); + assert!(fd >= 0); SockRef { - socket: ManuallyDrop::new(unsafe { Socket::from_raw_fd(socket.as_raw_fd()) }), + socket: ManuallyDrop::new(unsafe { Socket::from_raw_fd(fd) }), _lifetime: PhantomData, } } @@ -125,8 +127,10 @@ where { /// See the `From<&impl AsRawFd>` implementation. fn from(socket: &'s S) -> Self { + let socket = socket.as_raw_socket(); + assert!(socket != winapi::um::winsock2::INVALID_SOCKET as _); SockRef { - socket: ManuallyDrop::new(unsafe { Socket::from_raw_socket(socket.as_raw_socket()) }), + socket: ManuallyDrop::new(unsafe { Socket::from_raw_socket(socket) }), _lifetime: PhantomData, } } @@ -141,3 +145,11 @@ impl fmt::Debug for SockRef<'_> { .finish() } } + +#[test] +#[should_panic] +#[cfg(unix)] +fn sockref_from_invalid_fd() { + let raw: std::os::unix::io::RawFd = -1; + let _ = SockRef::from(&raw); +}