Write addrlen to user when writing socket addr

This commit is contained in:
Jianfeng Jiang 2023-08-01 11:34:57 +08:00 committed by Tate, Hongliang Tian
parent 87c50384f9
commit 93429ae2c9
5 changed files with 25 additions and 25 deletions

View File

@ -1,5 +1,4 @@
use crate::util::net::write_socket_addr_to_user; 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::{fs::file_table::FileDescripter, prelude::*};
use crate::{get_socket_without_holding_filetable_lock, log_syscall_entry}; use crate::{get_socket_without_holding_filetable_lock, log_syscall_entry};
@ -9,15 +8,14 @@ use super::SYS_ACCEPT;
pub fn sys_accept( pub fn sys_accept(
sockfd: FileDescripter, sockfd: FileDescripter,
sockaddr_ptr: Vaddr, sockaddr_ptr: Vaddr,
addr_len_ptr: Vaddr, addrlen_ptr: Vaddr,
) -> Result<SyscallReturn> { ) -> Result<SyscallReturn> {
log_syscall_entry!(SYS_ACCEPT); 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}, addrlen_ptr = 0x{addrlen_ptr:x}");
debug!("sockfd = {sockfd}, sockaddr_ptr = 0x{sockaddr_ptr:x}, addr_len = {addr_len}");
let current = current!(); let current = current!();
get_socket_without_holding_filetable_lock!(socket, current, sockfd); get_socket_without_holding_filetable_lock!(socket, current, sockfd);
let (connected_socket, socket_addr) = socket.accept()?; 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 fd = {
let mut file_table = current.file_table().lock(); let mut file_table = current.file_table().lock();
file_table.insert(connected_socket) file_table.insert(connected_socket)

View File

@ -1,5 +1,4 @@
use crate::util::net::write_socket_addr_to_user; 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 crate::{fs::file_table::FileDescripter, log_syscall_entry, prelude::*};
use super::SyscallReturn; use super::SyscallReturn;
@ -11,8 +10,7 @@ pub fn sys_getpeername(
addrlen_ptr: Vaddr, addrlen_ptr: Vaddr,
) -> Result<SyscallReturn> { ) -> Result<SyscallReturn> {
log_syscall_entry!(SYS_GETPEERNAME); log_syscall_entry!(SYS_GETPEERNAME);
let addrlen: i32 = read_val_from_user(addrlen_ptr)?; debug!("sockfd = {sockfd}, addr = 0x{addr:x}, addrlen_ptr = 0x{addrlen_ptr:x}");
debug!("sockfd = {sockfd}, addr = 0x{addr:x}, addrlen = {addrlen}");
let socket_addr = { let socket_addr = {
let current = current!(); let current = current!();
let file_table = current.file_table().lock(); let file_table = current.file_table().lock();
@ -20,6 +18,6 @@ pub fn sys_getpeername(
socket.peer_addr()? socket.peer_addr()?
}; };
// FIXME: trunscate write len if addrlen is not big enough // 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)) Ok(SyscallReturn::Return(0))
} }

View File

@ -2,7 +2,6 @@ use crate::fs::file_table::FileDescripter;
use crate::log_syscall_entry; use crate::log_syscall_entry;
use crate::prelude::*; use crate::prelude::*;
use crate::util::net::write_socket_addr_to_user; use crate::util::net::write_socket_addr_to_user;
use crate::util::read_val_from_user;
use super::SyscallReturn; use super::SyscallReturn;
use super::SYS_GETSOCKNAME; use super::SYS_GETSOCKNAME;
@ -13,8 +12,7 @@ pub fn sys_getsockname(
addrlen_ptr: Vaddr, addrlen_ptr: Vaddr,
) -> Result<SyscallReturn> { ) -> Result<SyscallReturn> {
log_syscall_entry!(SYS_GETSOCKNAME); log_syscall_entry!(SYS_GETSOCKNAME);
let addrlen: i32 = read_val_from_user(addrlen_ptr)?; debug!("sockfd = {sockfd}, addr = 0x{addr:x}, addrlen_ptr = 0x{addrlen_ptr:x}");
debug!("sockfd = {sockfd}, addr = 0x{addr:x}, addrlen = {addrlen}");
let socket_addr = { let socket_addr = {
let current = current!(); let current = current!();
let file_table = current.file_table().lock(); let file_table = current.file_table().lock();
@ -22,6 +20,6 @@ pub fn sys_getsockname(
socket.addr()? socket.addr()?
}; };
// FIXME: trunscate write len if addrlen is not big enough // 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)) Ok(SyscallReturn::Return(0))
} }

View File

@ -1,6 +1,6 @@
use crate::net::socket::SendRecvFlags; use crate::net::socket::SendRecvFlags;
use crate::util::net::write_socket_addr_to_user; 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::{fs::file_table::FileDescripter, prelude::*};
use crate::{get_socket_without_holding_filetable_lock, log_syscall_entry}; use crate::{get_socket_without_holding_filetable_lock, log_syscall_entry};
@ -13,11 +13,11 @@ pub fn sys_recvfrom(
len: usize, len: usize,
flags: i32, flags: i32,
src_addr: Vaddr, src_addr: Vaddr,
addrlen: Vaddr, addrlen_ptr: Vaddr,
) -> Result<SyscallReturn> { ) -> Result<SyscallReturn> {
log_syscall_entry!(SYS_RECVFROM); log_syscall_entry!(SYS_RECVFROM);
let flags = SendRecvFlags::from_bits_truncate(flags); 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!(); let current = current!();
get_socket_without_holding_filetable_lock!(socket, current, sockfd); get_socket_without_holding_filetable_lock!(socket, current, sockfd);
let mut buffer = vec![0u8; len]; let mut buffer = vec![0u8; len];
@ -26,10 +26,7 @@ pub fn sys_recvfrom(
write_bytes_to_user(buf, &buffer[..recv_size])?; write_bytes_to_user(buf, &buffer[..recv_size])?;
} }
if src_addr != 0 { if src_addr != 0 {
debug_assert!(addrlen != 0); write_socket_addr_to_user(&socket_addr, src_addr, addrlen_ptr)?;
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))?;
} }
Ok(SyscallReturn::Return(recv_size as _)) Ok(SyscallReturn::Return(recv_size as _))
} }

View File

@ -49,15 +49,20 @@ pub fn read_socket_addr_from_user(addr: Vaddr, addr_len: usize) -> Result<Socket
pub fn write_socket_addr_to_user( pub fn write_socket_addr_to_user(
socket_addr: &SocketAddr, socket_addr: &SocketAddr,
dest: Vaddr, dest: Vaddr,
max_len: usize, addrlen_ptr: Vaddr,
) -> Result<usize> { ) -> Result<()> {
match socket_addr { 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::<i32>(addrlen_ptr)? as usize;
let write_size = match socket_addr {
SocketAddr::Unix(path) => { SocketAddr::Unix(path) => {
let sock_addr_unix = SockAddrUnix::try_from(path.as_str())?; let sock_addr_unix = SockAddrUnix::try_from(path.as_str())?;
let write_size = core::mem::size_of::<SockAddrUnix>(); let write_size = core::mem::size_of::<SockAddrUnix>();
debug_assert!(max_len >= write_size); debug_assert!(max_len >= write_size);
write_val_to_user(dest, &sock_addr_unix)?; write_val_to_user(dest, &sock_addr_unix)?;
Ok(write_size) write_size as i32
} }
SocketAddr::IPv4(addr, port) => { SocketAddr::IPv4(addr, port) => {
let in_addr = InetAddr::from(*addr); let in_addr = InetAddr::from(*addr);
@ -65,10 +70,14 @@ pub fn write_socket_addr_to_user(
let write_size = core::mem::size_of::<SockAddrInet>(); let write_size = core::mem::size_of::<SockAddrInet>();
debug_assert!(max_len >= write_size); debug_assert!(max_len >= write_size);
write_val_to_user(dest, &sock_addr_in)?; write_val_to_user(dest, &sock_addr_in)?;
Ok(write_size) write_size as i32
} }
SocketAddr::IPv6 => todo!(), SocketAddr::IPv6 => todo!(),
};
if addrlen_ptr != 0 {
write_val_to_user(addrlen_ptr, &write_size)?;
} }
Ok(())
} }
#[derive(Debug, Clone, Copy, Pod)] #[derive(Debug, Clone, Copy, Pod)]