From f0f67954fe4a0d279c5a9483c6636020863de75a Mon Sep 17 00:00:00 2001 From: Alan Somers Date: Sun, 13 Mar 2022 16:16:25 -0600 Subject: Fix a panic in Linkaddr::addr The function assumed something about the values of the sockaddr_dl's fields. But because the inner type is public, we musn't do that. The only solution is to change the function's signature to return an Option. --- CHANGELOG.md | 2 ++ src/sys/socket/addr.rs | 71 +++++++++++++++++++++++++++++++++++--------------- 2 files changed, 52 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ad743cb..2e2e06b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -76,6 +76,8 @@ This project adheres to [Semantic Versioning](https://semver.org/). - `InetAddr::from_std` now sets the `sin_len`/`sin6_len` fields on the BSDs. (#[1642](https://github.com/nix-rust/nix/pull/1642)) +- Fixed a panic in `LinkAddr::addr`. That function now returns an `Option`. + (#[1675](https://github.com/nix-rust/nix/pull/1675)) ### Removed diff --git a/src/sys/socket/addr.rs b/src/sys/socket/addr.rs index 51999a3d..9fd9e30a 100644 --- a/src/sys/socket/addr.rs +++ b/src/sys/socket/addr.rs @@ -1446,33 +1446,38 @@ mod datalink { } /// Physical-layer address (MAC) - pub fn addr(&self) -> [u8; 6] { + pub fn addr(&self) -> Option<[u8; 6]> { let nlen = self.nlen(); let data = self.0.sdl_data; - assert!(!self.is_empty()); - - [ - data[nlen] as u8, - data[nlen + 1] as u8, - data[nlen + 2] as u8, - data[nlen + 3] as u8, - data[nlen + 4] as u8, - data[nlen + 5] as u8, - ] + if self.is_empty() { + None + } else { + Some([ + data[nlen] as u8, + data[nlen + 1] as u8, + data[nlen + 2] as u8, + data[nlen + 3] as u8, + data[nlen + 4] as u8, + data[nlen + 5] as u8, + ]) + } } } impl fmt::Display for LinkAddr { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let addr = self.addr(); - write!(f, "{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}", - addr[0], - addr[1], - addr[2], - addr[3], - addr[4], - addr[5]) + if let Some(addr) = self.addr() { + write!(f, "{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}", + addr[0], + addr[1], + addr[2], + addr[3], + addr[4], + addr[5]) + } else { + Ok(()) + } } } } @@ -1558,6 +1563,28 @@ mod tests { target_os = "openbsd"))] use super::*; + /// Don't panic when trying to display an empty datalink address + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd"))] + #[test] + fn test_datalink_display() { + let la = LinkAddr(libc::sockaddr_dl{ + sdl_len: 56, + sdl_family: 18, + sdl_index: 5, + sdl_type: 24, + sdl_nlen: 3, + sdl_alen: 0, + sdl_slen: 0, + .. unsafe{mem::zeroed()} + }); + format!("{}", la); + } + #[cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "ios", @@ -1593,7 +1620,8 @@ mod tests { match sock_addr { SockAddr::Link(ether_addr) => { - assert_eq!(ether_addr.addr(), [24u8, 101, 144, 221, 76, 176]); + assert_eq!(ether_addr.addr(), + Some([24u8, 101, 144, 221, 76, 176])); }, _ => { unreachable!() } }; @@ -1615,7 +1643,8 @@ mod tests { match sock_addr { SockAddr::Link(ether_addr) => { - assert_eq!(ether_addr.addr(), [24u8, 101, 144, 221, 76, 176]); + assert_eq!(ether_addr.addr(), + Some([24u8, 101, 144, 221, 76, 176])); }, _ => { unreachable!() } }; -- cgit v1.2.3 From e08c47cf1ee92381d7cc43a16db44d4f25fe74f8 Mon Sep 17 00:00:00 2001 From: Alan Somers Date: Sun, 13 Mar 2022 16:36:34 -0600 Subject: Fix the build on DragonflyBSD with -Zminimal-versions --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 039341d4..e5b0831e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,7 +27,7 @@ targets = [ ] [dependencies] -libc = { version = "0.2.114", features = [ "extra_traits" ] } +libc = { version = "0.2.115", features = [ "extra_traits" ] } bitflags = "1.1" cfg-if = "1.0" -- cgit v1.2.3