From 93429ae2c9434acfb58e6199987df07e51ed541f Mon Sep 17 00:00:00 2001 From: Jianfeng Jiang Date: Tue, 1 Aug 2023 11:34:57 +0800 Subject: [PATCH] Write addrlen to user when writing socket addr --- services/libs/jinux-std/src/syscall/accept.rs | 8 +++----- .../libs/jinux-std/src/syscall/getpeername.rs | 6 ++---- .../libs/jinux-std/src/syscall/getsockname.rs | 6 ++---- .../libs/jinux-std/src/syscall/recvfrom.rs | 11 ++++------- services/libs/jinux-std/src/util/net/addr.rs | 19 ++++++++++++++----- 5 files changed, 25 insertions(+), 25 deletions(-) diff --git a/services/libs/jinux-std/src/syscall/accept.rs b/services/libs/jinux-std/src/syscall/accept.rs index fcce6f0c8..76ed1ae89 100644 --- a/services/libs/jinux-std/src/syscall/accept.rs +++ b/services/libs/jinux-std/src/syscall/accept.rs @@ -1,5 +1,4 @@ use crate::util::net::write_socket_addr_to_user; -use crate::util::read_val_from_user; use crate::{fs::file_table::FileDescripter, prelude::*}; use crate::{get_socket_without_holding_filetable_lock, log_syscall_entry}; @@ -9,15 +8,14 @@ use super::SYS_ACCEPT; pub fn sys_accept( sockfd: FileDescripter, sockaddr_ptr: Vaddr, - addr_len_ptr: Vaddr, + addrlen_ptr: Vaddr, ) -> Result { log_syscall_entry!(SYS_ACCEPT); - let addr_len: i32 = read_val_from_user(addr_len_ptr)?; - debug!("sockfd = {sockfd}, sockaddr_ptr = 0x{sockaddr_ptr:x}, addr_len = {addr_len}"); + debug!("sockfd = {sockfd}, sockaddr_ptr = 0x{sockaddr_ptr:x}, addrlen_ptr = 0x{addrlen_ptr:x}"); let current = current!(); get_socket_without_holding_filetable_lock!(socket, current, sockfd); let (connected_socket, socket_addr) = socket.accept()?; - write_socket_addr_to_user(&socket_addr, sockaddr_ptr, addr_len as usize)?; + write_socket_addr_to_user(&socket_addr, sockaddr_ptr, addrlen_ptr)?; let fd = { let mut file_table = current.file_table().lock(); file_table.insert(connected_socket) diff --git a/services/libs/jinux-std/src/syscall/getpeername.rs b/services/libs/jinux-std/src/syscall/getpeername.rs index ad232844c..fa1e945b5 100644 --- a/services/libs/jinux-std/src/syscall/getpeername.rs +++ b/services/libs/jinux-std/src/syscall/getpeername.rs @@ -1,5 +1,4 @@ use crate::util::net::write_socket_addr_to_user; -use crate::util::read_val_from_user; use crate::{fs::file_table::FileDescripter, log_syscall_entry, prelude::*}; use super::SyscallReturn; @@ -11,8 +10,7 @@ pub fn sys_getpeername( addrlen_ptr: Vaddr, ) -> Result { log_syscall_entry!(SYS_GETPEERNAME); - let addrlen: i32 = read_val_from_user(addrlen_ptr)?; - debug!("sockfd = {sockfd}, addr = 0x{addr:x}, addrlen = {addrlen}"); + debug!("sockfd = {sockfd}, addr = 0x{addr:x}, addrlen_ptr = 0x{addrlen_ptr:x}"); let socket_addr = { let current = current!(); let file_table = current.file_table().lock(); @@ -20,6 +18,6 @@ pub fn sys_getpeername( socket.peer_addr()? }; // FIXME: trunscate write len if addrlen is not big enough - write_socket_addr_to_user(&socket_addr, addr, addrlen as usize)?; + write_socket_addr_to_user(&socket_addr, addr, addrlen_ptr)?; Ok(SyscallReturn::Return(0)) } diff --git a/services/libs/jinux-std/src/syscall/getsockname.rs b/services/libs/jinux-std/src/syscall/getsockname.rs index 12f080047..efea64187 100644 --- a/services/libs/jinux-std/src/syscall/getsockname.rs +++ b/services/libs/jinux-std/src/syscall/getsockname.rs @@ -2,7 +2,6 @@ use crate::fs::file_table::FileDescripter; use crate::log_syscall_entry; use crate::prelude::*; use crate::util::net::write_socket_addr_to_user; -use crate::util::read_val_from_user; use super::SyscallReturn; use super::SYS_GETSOCKNAME; @@ -13,8 +12,7 @@ pub fn sys_getsockname( addrlen_ptr: Vaddr, ) -> Result { log_syscall_entry!(SYS_GETSOCKNAME); - let addrlen: i32 = read_val_from_user(addrlen_ptr)?; - debug!("sockfd = {sockfd}, addr = 0x{addr:x}, addrlen = {addrlen}"); + debug!("sockfd = {sockfd}, addr = 0x{addr:x}, addrlen_ptr = 0x{addrlen_ptr:x}"); let socket_addr = { let current = current!(); let file_table = current.file_table().lock(); @@ -22,6 +20,6 @@ pub fn sys_getsockname( socket.addr()? }; // FIXME: trunscate write len if addrlen is not big enough - write_socket_addr_to_user(&socket_addr, addr, addrlen as usize)?; + write_socket_addr_to_user(&socket_addr, addr, addrlen_ptr)?; Ok(SyscallReturn::Return(0)) } diff --git a/services/libs/jinux-std/src/syscall/recvfrom.rs b/services/libs/jinux-std/src/syscall/recvfrom.rs index 3dccf15b6..4b4781937 100644 --- a/services/libs/jinux-std/src/syscall/recvfrom.rs +++ b/services/libs/jinux-std/src/syscall/recvfrom.rs @@ -1,6 +1,6 @@ use crate::net::socket::SendRecvFlags; use crate::util::net::write_socket_addr_to_user; -use crate::util::{read_val_from_user, write_bytes_to_user, write_val_to_user}; +use crate::util::write_bytes_to_user; use crate::{fs::file_table::FileDescripter, prelude::*}; use crate::{get_socket_without_holding_filetable_lock, log_syscall_entry}; @@ -13,11 +13,11 @@ pub fn sys_recvfrom( len: usize, flags: i32, src_addr: Vaddr, - addrlen: Vaddr, + addrlen_ptr: Vaddr, ) -> Result { log_syscall_entry!(SYS_RECVFROM); let flags = SendRecvFlags::from_bits_truncate(flags); - debug!("sockfd = {sockfd}, buf = 0x{buf:x}, len = {len}, flags = {flags:?}, src_addr = 0x{src_addr:x}, addrlen = 0x{addrlen:x}"); + debug!("sockfd = {sockfd}, buf = 0x{buf:x}, len = {len}, flags = {flags:?}, src_addr = 0x{src_addr:x}, addrlen_ptr = 0x{addrlen_ptr:x}"); let current = current!(); get_socket_without_holding_filetable_lock!(socket, current, sockfd); let mut buffer = vec![0u8; len]; @@ -26,10 +26,7 @@ pub fn sys_recvfrom( write_bytes_to_user(buf, &buffer[..recv_size])?; } if src_addr != 0 { - debug_assert!(addrlen != 0); - let max_len: u32 = read_val_from_user(addrlen)?; - let write_size = write_socket_addr_to_user(&socket_addr, src_addr, max_len as usize)?; - write_val_to_user(addrlen, &(write_size as u32))?; + write_socket_addr_to_user(&socket_addr, src_addr, addrlen_ptr)?; } Ok(SyscallReturn::Return(recv_size as _)) } diff --git a/services/libs/jinux-std/src/util/net/addr.rs b/services/libs/jinux-std/src/util/net/addr.rs index 8228888f2..1af19e824 100644 --- a/services/libs/jinux-std/src/util/net/addr.rs +++ b/services/libs/jinux-std/src/util/net/addr.rs @@ -49,15 +49,20 @@ pub fn read_socket_addr_from_user(addr: Vaddr, addr_len: usize) -> Result Result { - match socket_addr { + addrlen_ptr: Vaddr, +) -> Result<()> { + debug_assert!(addrlen_ptr != 0); + if addrlen_ptr == 0 { + return_errno_with_message!(Errno::EINVAL, "must provide the addrlen ptr"); + } + let max_len = read_val_from_user::(addrlen_ptr)? as usize; + let write_size = match socket_addr { SocketAddr::Unix(path) => { let sock_addr_unix = SockAddrUnix::try_from(path.as_str())?; let write_size = core::mem::size_of::(); debug_assert!(max_len >= write_size); write_val_to_user(dest, &sock_addr_unix)?; - Ok(write_size) + write_size as i32 } SocketAddr::IPv4(addr, port) => { let in_addr = InetAddr::from(*addr); @@ -65,10 +70,14 @@ pub fn write_socket_addr_to_user( let write_size = core::mem::size_of::(); debug_assert!(max_len >= write_size); write_val_to_user(dest, &sock_addr_in)?; - Ok(write_size) + write_size as i32 } SocketAddr::IPv6 => todo!(), + }; + if addrlen_ptr != 0 { + write_val_to_user(addrlen_ptr, &write_size)?; } + Ok(()) } #[derive(Debug, Clone, Copy, Pod)]