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::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<SyscallReturn> {
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)

View File

@ -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<SyscallReturn> {
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))
}

View File

@ -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<SyscallReturn> {
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))
}

View File

@ -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<SyscallReturn> {
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 _))
}

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(
socket_addr: &SocketAddr,
dest: Vaddr,
max_len: usize,
) -> Result<usize> {
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::<i32>(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::<SockAddrUnix>();
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::<SockAddrInet>();
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)]