Skip to content

Commit 2854888

Browse files
bors[bot]asomers
andauthored
Merge #1702
1702: Fix UnixAddr::size on Linux and Android r=rtzoeller a=asomers SockaddrLike::size() is meant to return the amount of space that can be used to store the sockaddr. But on Linux-based OSes, UnixAddr contains an extra field to store the address's length. This field is not part of the address, and should not contribute to the value of size(). This bug can't cause an out-of-bounds write, and every OS that we test on can tolerate the greater-than-expected length, but it might confuse applications that implement functions similar to getsockname in userland. Co-authored-by: Alan Somers <[email protected]>
2 parents 9793aaf + db969c5 commit 2854888

File tree

2 files changed

+51
-2
lines changed

2 files changed

+51
-2
lines changed

CHANGELOG.md

+10
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,16 @@
33
All notable changes to this project will be documented in this file.
44
This project adheres to [Semantic Versioning](https://semver.org/).
55

6+
## [Unreleased] - ReleaseDate
7+
### Added
8+
### Changed
9+
### Fixed
10+
11+
- Fixed `UnixAddr::size` on Linux-based OSes.
12+
(#[1702](https://github.com/nix-rust/nix/pull/1702))
13+
14+
### Removed
15+
616
## [0.24.0] - 2022-04-21
717
### Added
818

src/sys/socket/addr.rs

+41-2
Original file line numberDiff line numberDiff line change
@@ -953,6 +953,10 @@ impl SockaddrLike for UnixAddr {
953953
ptr::copy(addr as *const u8, sup, su_len as usize);
954954
Some(Self::from_raw_parts(su, su_len as u8))
955955
}
956+
957+
fn size() -> libc::socklen_t where Self: Sized {
958+
mem::size_of::<libc::sockaddr_un>() as libc::socklen_t
959+
}
956960
}
957961

958962
impl AsRef<libc::sockaddr_un> for UnixAddr {
@@ -2615,11 +2619,12 @@ mod tests {
26152619
}
26162620

26172621
mod link {
2622+
use super::*;
26182623
#[cfg(any(target_os = "ios",
26192624
target_os = "macos",
26202625
target_os = "illumos"
26212626
))]
2622-
use super::{*, super::super::socklen_t};
2627+
use super::super::super::socklen_t;
26232628

26242629
/// Don't panic when trying to display an empty datalink address
26252630
#[cfg(any(target_os = "dragonfly",
@@ -2701,6 +2706,24 @@ mod tests {
27012706
assert_eq!(sock_addr.as_link_addr().unwrap().addr(),
27022707
Some([24u8, 101, 144, 221, 76, 176]));
27032708
}
2709+
2710+
#[test]
2711+
fn size() {
2712+
#[cfg(any(target_os = "dragonfly",
2713+
target_os = "freebsd",
2714+
target_os = "ios",
2715+
target_os = "macos",
2716+
target_os = "netbsd",
2717+
target_os = "illumos",
2718+
target_os = "openbsd"))]
2719+
let l = mem::size_of::<libc::sockaddr_dl>();
2720+
#[cfg(any(
2721+
target_os = "android",
2722+
target_os = "fuchsia",
2723+
target_os = "linux"))]
2724+
let l = mem::size_of::<libc::sockaddr_ll>();
2725+
assert_eq!( LinkAddr::size() as usize, l);
2726+
}
27042727
}
27052728

27062729
mod sockaddr_in {
@@ -2713,6 +2736,12 @@ mod tests {
27132736
let addr = SockaddrIn::from_str(s).unwrap();
27142737
assert_eq!(s, format!("{}", addr));
27152738
}
2739+
2740+
#[test]
2741+
fn size() {
2742+
assert_eq!(mem::size_of::<libc::sockaddr_in>(),
2743+
SockaddrIn::size() as usize);
2744+
}
27162745
}
27172746

27182747
mod sockaddr_in6 {
@@ -2725,10 +2754,15 @@ mod tests {
27252754
let addr = SockaddrIn6::from_str(s).unwrap();
27262755
assert_eq!(s, format!("{}", addr));
27272756
}
2757+
2758+
#[test]
2759+
fn size() {
2760+
assert_eq!(mem::size_of::<libc::sockaddr_in6>(),
2761+
SockaddrIn6::size() as usize);
2762+
}
27282763
}
27292764

27302765
mod unixaddr {
2731-
#[cfg(any(target_os = "android", target_os = "linux"))]
27322766
use super::*;
27332767

27342768
#[cfg(any(target_os = "android", target_os = "linux"))]
@@ -2742,5 +2776,10 @@ mod tests {
27422776
assert_eq!(sun_path1, sun_path2);
27432777
}
27442778

2779+
#[test]
2780+
fn size() {
2781+
assert_eq!(mem::size_of::<libc::sockaddr_un>(),
2782+
UnixAddr::size() as usize);
2783+
}
27452784
}
27462785
}

0 commit comments

Comments
 (0)