mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2025-02-10 12:09:31 +00:00
base: net: Validate descriptor passed to UnixSeqpacketListener
The existing file descriptor must refer to a listening socket. TEST=cargo test, added a new unit test BUG=b:238931628 Change-Id: Ia6bd5d6d30af69fb4b5fa00865f5528f19f569d9 Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/3932714 Commit-Queue: Keir Fraser <keirf@google.com> Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
This commit is contained in:
parent
d1a1397542
commit
88674cade9
1 changed files with 42 additions and 0 deletions
|
@ -726,6 +726,26 @@ impl UnixSeqpacketListener {
|
|||
.expect("fd filename should be unicode")
|
||||
.parse::<i32>()
|
||||
.expect("fd should be an integer");
|
||||
let mut result: c_int = 0;
|
||||
let mut result_len = size_of::<c_int>() as libc::socklen_t;
|
||||
let ret = unsafe {
|
||||
libc::getsockopt(
|
||||
fd,
|
||||
libc::SOL_SOCKET,
|
||||
libc::SO_ACCEPTCONN,
|
||||
&mut result as *mut _ as *mut libc::c_void,
|
||||
&mut result_len,
|
||||
)
|
||||
};
|
||||
if ret < 0 {
|
||||
return Err(io::Error::last_os_error());
|
||||
}
|
||||
if result != 1 {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::InvalidInput,
|
||||
"specified descriptor is not a listening socket",
|
||||
));
|
||||
}
|
||||
return Ok(UnixSeqpacketListener { fd });
|
||||
}
|
||||
// Safe socket initialization since we handle the returned error.
|
||||
|
@ -976,6 +996,28 @@ mod tests {
|
|||
assert_eq!(socket_path, listener_path);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unix_seqpacket_listener_from_fd() {
|
||||
let mut socket_path = tmpdir();
|
||||
socket_path.push("unix_seqpacket_listener_from_fd");
|
||||
let listener = UnlinkUnixSeqpacketListener(
|
||||
UnixSeqpacketListener::bind(&socket_path)
|
||||
.expect("failed to create UnixSeqpacketListener"),
|
||||
);
|
||||
// UnixSeqpacketListener should succeed on a valid listening desriptor.
|
||||
let good_dup = UnixSeqpacketListener::bind(&format!("/proc/self/fd/{}", unsafe {
|
||||
libc::dup(listener.as_raw_fd())
|
||||
}));
|
||||
good_dup.expect("failed to create dup UnixSeqpacketListener");
|
||||
// UnixSeqpacketListener must fail on an existing non-listener socket.
|
||||
let s1 =
|
||||
UnixSeqpacket::connect(socket_path.as_path()).expect("UnixSeqpacket::connect failed");
|
||||
let bad_dup = UnixSeqpacketListener::bind(&format!("/proc/self/fd/{}", unsafe {
|
||||
libc::dup(s1.as_raw_fd())
|
||||
}));
|
||||
assert!(bad_dup.is_err())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unix_seqpacket_path_exists_pass() {
|
||||
let mut socket_path = tmpdir();
|
||||
|
|
Loading…
Reference in a new issue