From 39ce623d2df545a6ebea65038e4882b2bbef08c1 Mon Sep 17 00:00:00 2001 From: jD91mZM2 <me@krake.one> Date: Mon, 29 Jun 2020 11:36:07 +0200 Subject: [PATCH] Fix bind/connect's AF_UNIX socket path... again I don't really know for sure what all these silly rules are, but I think I got it now... --- src/header/sys_un/mod.rs | 2 +- src/platform/redox/socket.rs | 24 +++++++++++++++++++++--- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/header/sys_un/mod.rs b/src/header/sys_un/mod.rs index b5738899..63d26c8f 100644 --- a/src/header/sys_un/mod.rs +++ b/src/header/sys_un/mod.rs @@ -7,7 +7,7 @@ pub struct sockaddr_un { } impl sockaddr_un { - pub fn path_len(&self) -> usize { + pub fn path_offset(&self) -> usize { let base = self as *const _ as usize; let path = &self.sun_path as *const _ as usize; trace!("base: {:#X}, path: {:#X}", base, path); diff --git a/src/platform/redox/socket.rs b/src/platform/redox/socket.rs index 60ecdcd6..c7e55088 100644 --- a/src/platform/redox/socket.rs +++ b/src/platform/redox/socket.rs @@ -9,6 +9,7 @@ use super::{ use crate::header::{ arpa_inet::inet_aton, netinet_in::{in_port_t, sockaddr_in, in_addr}, + string::strnlen, sys_socket::{constants::*, sa_family_t, sockaddr, socklen_t}, sys_time::timeval, sys_un::sockaddr_un, @@ -62,15 +63,32 @@ macro_rules! bind_or_connect { }, AF_UNIX => { let data = &*($address as *const sockaddr_un); - trace!("address: {:p}, data: {:p}, data2: {:#X}", $address, data, data as *const _ as usize); + + // NOTE: It's UB to access data in given address that exceeds + // the given address length. + + let maxlen = cmp::min( + // Max path length of the full-sized struct + data.sun_path.len(), + // Length inferred from given addrlen + $address_len as usize - data.path_offset() + ); + let len = cmp::min( + // The maximum length of the address + maxlen, + // The first NUL byte, if any + strnlen(&data.sun_path as *const _, maxlen as size_t), + ); + let addr = slice::from_raw_parts( &data.sun_path as *const _ as *const u8, - $address_len as usize - data.path_len(), + len, ); let path = format!( "{}", str::from_utf8(addr).unwrap() ); + trace!("path: {:?}", path); path }, @@ -96,7 +114,7 @@ unsafe fn inner_af_unix(buf: &[u8], address: *mut sockaddr, address_len: *mut so let path = slice::from_raw_parts_mut( &mut data.sun_path as *mut _ as *mut u8, - data.path_len(), + data.sun_path.len(), ); let len = cmp::min(path.len(), buf.len()); -- GitLab