Skip to content

Commit

Permalink
Merge #1675
Browse files Browse the repository at this point in the history
1675: Fix a panic in Linkaddr::addr r=rtzoeller a=asomers

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.

Co-authored-by: Alan Somers <asomers@gmail.com>
  • Loading branch information
bors[bot] and asomers committed Mar 13, 2022
2 parents bf59a6c + 76e6e5e commit a222989
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 20 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
69 changes: 49 additions & 20 deletions src/sys/socket/addr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(())
}
}
}
}
Expand Down Expand Up @@ -1558,6 +1563,29 @@ 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 = "illumos",
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,
sdl_data: unsafe{mem::zeroed()}
});
format!("{}", la);
}

#[cfg(any(target_os = "dragonfly",
target_os = "freebsd",
target_os = "ios",
Expand Down Expand Up @@ -1593,7 +1621,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!() }
};
Expand Down

0 comments on commit a222989

Please sign in to comment.