Skip to content

Commit 1546857

Browse files
committed
For invalid IP address conversions with future Rust versions
Rust's standard library no longer guarantees that Ipv4Addr and Ipv6Addr are wrappers around the C types (though for now at least, they are identical on all platforms I'm aware of). So do the conversions explicitly instead of transmuting. Fixes #2053
1 parent 9a3010b commit 1546857

File tree

3 files changed

+11
-11
lines changed

3 files changed

+11
-11
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ This project adheres to [Semantic Versioning](https://semver.org/).
4040
([#1964](https://github.com/nix-rust/nix/pull/1964))
4141
- Fix: send ETH_P_ALL in htons format
4242
([#1925](https://github.com/nix-rust/nix/pull/1925))
43+
- Fix potentially invalid conversions in
44+
`SockaddrIn::from<std::net::SocketAddrV4>`,
45+
`SockaddrIn6::from<std::net::SockaddrV6>`, `IpMembershipRequest::new`, and
46+
`Ipv6MembershipRequest::new` with future Rust versions.
47+
([#2061](https://github.com/nix-rust/nix/pull/2061))
4348

4449
### Removed
4550

Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ libc = { version = "0.2.141", features = ["extra_traits"] }
3131
bitflags = "1.1"
3232
cfg-if = "1.0"
3333
pin-utils = { version = "0.1.0", optional = true }
34-
static_assertions = "1"
3534
memoffset = { version = "0.9", optional = true }
3635

3736
[features]

src/sys/socket/addr.rs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -39,18 +39,17 @@ use std::{fmt, mem, net, ptr, slice};
3939
/// Convert a std::net::Ipv4Addr into the libc form.
4040
#[cfg(feature = "net")]
4141
pub(crate) const fn ipv4addr_to_libc(addr: net::Ipv4Addr) -> libc::in_addr {
42-
static_assertions::assert_eq_size!(net::Ipv4Addr, libc::in_addr);
43-
// Safe because both types have the same memory layout, and no fancy Drop
44-
// impls.
45-
unsafe { mem::transmute(addr) }
42+
libc::in_addr {
43+
s_addr: u32::from_ne_bytes(addr.octets())
44+
}
4645
}
4746

4847
/// Convert a std::net::Ipv6Addr into the libc form.
4948
#[cfg(feature = "net")]
5049
pub(crate) const fn ipv6addr_to_libc(addr: &net::Ipv6Addr) -> libc::in6_addr {
51-
static_assertions::assert_eq_size!(net::Ipv6Addr, libc::in6_addr);
52-
// Safe because both are Newtype wrappers around the same libc type
53-
unsafe { mem::transmute(*addr) }
50+
libc::in6_addr {
51+
s6_addr: addr.octets()
52+
}
5453
}
5554

5655
/// These constants specify the protocol family to be used
@@ -949,9 +948,6 @@ impl SockaddrLike for () {
949948
}
950949

951950
/// An IPv4 socket address
952-
// This is identical to net::SocketAddrV4. But the standard library
953-
// doesn't allow direct access to the libc fields, which we need. So we
954-
// reimplement it here.
955951
#[cfg(feature = "net")]
956952
#[repr(transparent)]
957953
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]

0 commit comments

Comments
 (0)