Skip to content

Commit af45859

Browse files
committed
Make SockAddr::as_ffi_pair safe
It was only marked unsafe because it did a pointer cast, but that particular pointer cast is always allowed by C.
1 parent 3094772 commit af45859

File tree

3 files changed

+40
-11
lines changed

3 files changed

+40
-11
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
5050
`offset_of!`.
5151
- `sys::socket::sockaddr_storage_to_addr`, `offset_of!`, and `Errno::clear` are
5252
no longer `unsafe`.
53+
- `SockAddr::as_ffi_pair`,`sys::socket::sockaddr_storage_to_addr`, `offset_of!`,
54+
and `Errno::clear` are no longer `unsafe`.
5355
(#[1244](https://github.com/nix-rust/nix/pull/1244))
5456
- Several `Inotify` methods now take `self` by value instead of by reference
5557
(#[1244](https://github.com/nix-rust/nix/pull/1244))

src/sys/socket/addr.rs

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -768,39 +768,60 @@ impl SockAddr {
768768
/// with the size of the actual data type. sockaddr is commonly used as a proxy for
769769
/// a superclass as C doesn't support inheritance, so many functions that take
770770
/// a sockaddr * need to take the size of the underlying type as well and then internally cast it back.
771-
pub unsafe fn as_ffi_pair(&self) -> (&libc::sockaddr, libc::socklen_t) {
771+
pub fn as_ffi_pair(&self) -> (&libc::sockaddr, libc::socklen_t) {
772772
match *self {
773773
SockAddr::Inet(InetAddr::V4(ref addr)) => (
774-
&*(addr as *const libc::sockaddr_in as *const libc::sockaddr),
774+
// This cast is always allowed in C
775+
unsafe {
776+
&*(addr as *const libc::sockaddr_in as *const libc::sockaddr)
777+
},
775778
mem::size_of_val(addr) as libc::socklen_t
776779
),
777780
SockAddr::Inet(InetAddr::V6(ref addr)) => (
778-
&*(addr as *const libc::sockaddr_in6 as *const libc::sockaddr),
781+
// This cast is always allowed in C
782+
unsafe {
783+
&*(addr as *const libc::sockaddr_in6 as *const libc::sockaddr)
784+
},
779785
mem::size_of_val(addr) as libc::socklen_t
780786
),
781787
SockAddr::Unix(UnixAddr(ref addr, len)) => (
782-
&*(addr as *const libc::sockaddr_un as *const libc::sockaddr),
788+
// This cast is always allowed in C
789+
unsafe {
790+
&*(addr as *const libc::sockaddr_un as *const libc::sockaddr)
791+
},
783792
(len + offset_of!(libc::sockaddr_un, sun_path)) as libc::socklen_t
784793
),
785794
#[cfg(any(target_os = "android", target_os = "linux"))]
786795
SockAddr::Netlink(NetlinkAddr(ref sa)) => (
787-
&*(sa as *const libc::sockaddr_nl as *const libc::sockaddr),
796+
// This cast is always allowed in C
797+
unsafe {
798+
&*(sa as *const libc::sockaddr_nl as *const libc::sockaddr)
799+
},
788800
mem::size_of_val(sa) as libc::socklen_t
789801
),
790802
#[cfg(any(target_os = "android", target_os = "linux"))]
791803
SockAddr::Alg(AlgAddr(ref sa)) => (
792-
&*(sa as *const libc::sockaddr_alg as *const libc::sockaddr),
804+
// This cast is always allowed in C
805+
unsafe {
806+
&*(sa as *const libc::sockaddr_alg as *const libc::sockaddr)
807+
},
793808
mem::size_of_val(sa) as libc::socklen_t
794809
),
795810
#[cfg(any(target_os = "ios", target_os = "macos"))]
796811
SockAddr::SysControl(SysControlAddr(ref sa)) => (
797-
&*(sa as *const libc::sockaddr_ctl as *const libc::sockaddr),
812+
// This cast is always allowed in C
813+
unsafe {
814+
&*(sa as *const libc::sockaddr_ctl as *const libc::sockaddr)
815+
},
798816
mem::size_of_val(sa) as libc::socklen_t
799817

800818
),
801819
#[cfg(any(target_os = "android", target_os = "linux"))]
802820
SockAddr::Link(LinkAddr(ref addr)) => (
803-
&*(addr as *const libc::sockaddr_ll as *const libc::sockaddr),
821+
// This cast is always allowed in C
822+
unsafe {
823+
&*(addr as *const libc::sockaddr_ll as *const libc::sockaddr)
824+
},
804825
mem::size_of_val(addr) as libc::socklen_t
805826
),
806827
#[cfg(any(target_os = "dragonfly",
@@ -810,12 +831,18 @@ impl SockAddr {
810831
target_os = "netbsd",
811832
target_os = "openbsd"))]
812833
SockAddr::Link(LinkAddr(ref addr)) => (
813-
&*(addr as *const libc::sockaddr_dl as *const libc::sockaddr),
834+
// This cast is always allowed in C
835+
unsafe {
836+
&*(addr as *const libc::sockaddr_dl as *const libc::sockaddr)
837+
},
814838
mem::size_of_val(addr) as libc::socklen_t
815839
),
816840
#[cfg(target_os = "linux")]
817841
SockAddr::Vsock(VsockAddr(ref sa)) => (
818-
&*(sa as *const libc::sockaddr_vm as *const libc::sockaddr),
842+
// This cast is always allowed in C
843+
unsafe {
844+
&*(sa as *const libc::sockaddr_vm as *const libc::sockaddr)
845+
},
819846
mem::size_of_val(sa) as libc::socklen_t
820847
),
821848
}

src/sys/socket/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1251,7 +1251,7 @@ fn pack_mhdr_to_send<'a, I, C>(
12511251
// Next encode the sending address, if provided
12521252
let (name, namelen) = match addr {
12531253
Some(addr) => {
1254-
let (x, y) = unsafe { addr.as_ffi_pair() };
1254+
let (x, y) = addr.as_ffi_pair();
12551255
(x as *const _, y)
12561256
},
12571257
None => (ptr::null(), 0),

0 commit comments

Comments
 (0)