From cb0a51d28dc75bd339b2f878124b6d59605e2eff Mon Sep 17 00:00:00 2001 From: Jiajie Chen Date: Sun, 10 Mar 2019 08:39:22 +0800 Subject: [PATCH] Use union to implement sockaddr, and eliminate many warnings --- kernel/src/process/structs.rs | 2 +- kernel/src/syscall/fs.rs | 22 ++-- kernel/src/syscall/mem.rs | 37 +++++-- kernel/src/syscall/misc.rs | 32 +++--- kernel/src/syscall/mod.rs | 16 +-- kernel/src/syscall/net.rs | 195 +++++++++++++++++++++------------- kernel/src/syscall/time.rs | 6 +- 7 files changed, 195 insertions(+), 115 deletions(-) diff --git a/kernel/src/process/structs.rs b/kernel/src/process/structs.rs index 96c9ba1..fb25f89 100644 --- a/kernel/src/process/structs.rs +++ b/kernel/src/process/structs.rs @@ -279,7 +279,7 @@ impl Process { fn memory_set_from(elf: &ElfFile<'_>) -> (MemorySet, usize) { debug!("creating MemorySet from ELF"); let mut ms = MemorySet::new(); - let mut entry = elf.header.pt2.entry_point() as usize; + let entry = elf.header.pt2.entry_point() as usize; // [NoMMU] Get total memory size and alloc space let va_begin = elf.program_iter() diff --git a/kernel/src/syscall/fs.rs b/kernel/src/syscall/fs.rs index dcac2c5..3c7f2cf 100644 --- a/kernel/src/syscall/fs.rs +++ b/kernel/src/syscall/fs.rs @@ -68,7 +68,7 @@ pub fn sys_write_file(proc: &mut Process, fd: usize, base: *const u8, len: usize pub fn sys_poll(ufds: *mut PollFd, nfds: usize, timeout_msecs: usize) -> SysResult { info!("poll: ufds: {:?}, nfds: {}, timeout_msecs: {:#x}", ufds, nfds, timeout_msecs); - let mut proc = process(); + let proc = process(); proc.memory_set.check_mut_array(ufds, nfds)?; let polls = unsafe { slice::from_raw_parts_mut(ufds, nfds) }; @@ -82,7 +82,7 @@ pub fn sys_poll(ufds: *mut PollFd, nfds: usize, timeout_msecs: usize) -> SysResu let begin_time_ms = crate::trap::uptime_msec(); loop { use PollEvents as PE; - let mut proc = process(); + let proc = process(); let mut events = 0; for poll in polls.iter_mut() { poll.revents = PE::NONE; @@ -192,7 +192,7 @@ impl FdSet { pub fn sys_select(nfds: usize, read: *mut u32, write: *mut u32, err: *mut u32, timeout: *const TimeVal) -> SysResult { info!("select: nfds: {}, read: {:?}, write: {:?}, err: {:?}, timeout: {:?}", nfds, read, write, err, timeout); - let mut proc = process(); + let proc = process(); let mut read_fds = FdSet::new(&proc, read, nfds)?; let mut write_fds = FdSet::new(&proc, write, nfds)?; let mut err_fds = FdSet::new(&proc, err, nfds)?; @@ -207,7 +207,7 @@ pub fn sys_select(nfds: usize, read: *mut u32, write: *mut u32, err: *mut u32, t let begin_time_ms = crate::trap::uptime_msec(); loop { - let mut proc = process(); + let proc = process(); let mut events = 0; for (fd, file) in proc.files.iter() { if *fd < nfds { @@ -336,7 +336,7 @@ pub fn sys_access(path: *const u8, mode: usize) -> SysResult { pub fn sys_getcwd(buf: *mut u8, len: usize) -> SysResult { info!("getcwd: buf: {:?}, len: {:#x}", buf, len); - let mut proc = process(); + let proc = process(); proc.memory_set.check_mut_array(buf, len)?; if proc.cwd.len() + 1 > len { return Err(SysError::ERANGE); @@ -364,7 +364,7 @@ pub fn sys_fstat(fd: usize, stat_ptr: *mut Stat) -> SysResult { } pub fn sys_lstat(path: *const u8, stat_ptr: *mut Stat) -> SysResult { - let mut proc = process(); + let proc = process(); let path = unsafe { proc.memory_set.check_and_clone_cstr(path)? }; proc.memory_set.check_mut_ptr(stat_ptr)?; info!("lstat: path: {}", path); @@ -403,7 +403,7 @@ pub fn sys_fdatasync(fd: usize) -> SysResult { } pub fn sys_truncate(path: *const u8, len: usize) -> SysResult { - let mut proc = process(); + let proc = process(); let path = unsafe { proc.memory_set.check_and_clone_cstr(path)? }; info!("truncate: path: {:?}, len: {}", path, len); proc.lookup_inode(&path)?.resize(len)?; @@ -480,7 +480,7 @@ pub fn sys_chdir(path: *const u8) -> SysResult { } pub fn sys_rename(oldpath: *const u8, newpath: *const u8) -> SysResult { - let mut proc = process(); + let proc = process(); let oldpath = unsafe { proc.memory_set.check_and_clone_cstr(oldpath)? }; let newpath = unsafe { proc.memory_set.check_and_clone_cstr(newpath)? }; info!("rename: oldpath: {:?}, newpath: {:?}", oldpath, newpath); @@ -499,7 +499,7 @@ pub fn sys_rename(oldpath: *const u8, newpath: *const u8) -> SysResult { } pub fn sys_mkdir(path: *const u8, mode: usize) -> SysResult { - let mut proc = process(); + let proc = process(); let path = unsafe { proc.memory_set.check_and_clone_cstr(path)? }; // TODO: check pathname info!("mkdir: path: {:?}, mode: {:#o}", path, mode); @@ -514,7 +514,7 @@ pub fn sys_mkdir(path: *const u8, mode: usize) -> SysResult { } pub fn sys_link(oldpath: *const u8, newpath: *const u8) -> SysResult { - let mut proc = process(); + let proc = process(); let oldpath = unsafe { proc.memory_set.check_and_clone_cstr(oldpath)? }; let newpath = unsafe { proc.memory_set.check_and_clone_cstr(newpath)? }; info!("link: oldpath: {:?}, newpath: {:?}", oldpath, newpath); @@ -527,7 +527,7 @@ pub fn sys_link(oldpath: *const u8, newpath: *const u8) -> SysResult { } pub fn sys_unlink(path: *const u8) -> SysResult { - let mut proc = process(); + let proc = process(); let path = unsafe { proc.memory_set.check_and_clone_cstr(path)? }; info!("unlink: path: {:?}", path); diff --git a/kernel/src/syscall/mem.rs b/kernel/src/syscall/mem.rs index 98c802e..6e04eab 100644 --- a/kernel/src/syscall/mem.rs +++ b/kernel/src/syscall/mem.rs @@ -8,10 +8,20 @@ use crate::memory::GlobalFrameAlloc; use super::*; -pub fn sys_mmap(mut addr: usize, mut len: usize, prot: usize, flags: usize, fd: i32, offset: usize) -> SysResult { +pub fn sys_mmap( + mut addr: usize, + len: usize, + prot: usize, + flags: usize, + fd: i32, + offset: usize, +) -> SysResult { let prot = MmapProt::from_bits_truncate(prot); let flags = MmapFlags::from_bits_truncate(flags); - info!("mmap: addr={:#x}, size={:#x}, prot={:?}, flags={:?}, fd={}, offset={:#x}", addr, len, prot, flags, fd, offset); + info!( + "mmap: addr={:#x}, size={:#x}, prot={:?}, flags={:?}, fd={}, offset={:#x}", + addr, len, prot, flags, fd, offset + ); let mut proc = process(); if addr == 0 { @@ -32,7 +42,13 @@ pub fn sys_mmap(mut addr: usize, mut len: usize, prot: usize, flags: usize, fd: if flags.contains(MmapFlags::SHARED) { return Err(SysError::EINVAL); } - proc.memory_set.push(addr, addr + len, prot.to_attr(), Delay::new(GlobalFrameAlloc), "mmap"); + proc.memory_set.push( + addr, + addr + len, + prot.to_attr(), + Delay::new(GlobalFrameAlloc), + "mmap", + ); return Ok(addr); } unimplemented!() @@ -40,7 +56,10 @@ pub fn sys_mmap(mut addr: usize, mut len: usize, prot: usize, flags: usize, fd: pub fn sys_mprotect(addr: usize, len: usize, prot: usize) -> SysResult { let prot = MmapProt::from_bits_truncate(prot); - info!("mprotect: addr={:#x}, size={:#x}, prot={:?}", addr, len, prot); + info!( + "mprotect: addr={:#x}, size={:#x}, prot={:?}", + addr, len, prot + ); let mut proc = process(); let attr = prot.to_attr(); @@ -53,7 +72,9 @@ pub fn sys_mprotect(addr: usize, len: usize, prot: usize) -> SysResult { } proc.memory_set.edit(|pt| { for page in Page::range_of(addr, addr + len) { - let entry = pt.get_entry(page.start_address()).expect("failed to get entry"); + let entry = pt + .get_entry(page.start_address()) + .expect("failed to get entry"); attr.apply(entry); } }); @@ -96,9 +117,11 @@ bitflags! { impl MmapProt { fn to_attr(self) -> MemoryAttr { let mut attr = MemoryAttr::default().user(); - if self.contains(MmapProt::EXEC) { attr = attr.execute(); } + if self.contains(MmapProt::EXEC) { + attr = attr.execute(); + } // FIXME: see sys_mprotect -// if !self.contains(MmapProt::WRITE) { attr = attr.readonly(); } + // if !self.contains(MmapProt::WRITE) { attr = attr.readonly(); } attr } } diff --git a/kernel/src/syscall/misc.rs b/kernel/src/syscall/misc.rs index 5d557ca..92abd55 100644 --- a/kernel/src/syscall/misc.rs +++ b/kernel/src/syscall/misc.rs @@ -54,23 +54,29 @@ pub fn sys_sysinfo(sys_info: *mut SysInfo) -> SysResult { proc.memory_set.check_mut_ptr(sys_info)?; let sysinfo = SysInfo::default(); - unsafe { - *sys_info = sysinfo - }; + unsafe { *sys_info = sysinfo }; Ok(0) } pub fn sys_futex(uaddr: usize, op: u32, val: i32, timeout: *const TimeSpec) -> SysResult { - info!("futex: [{}] uaddr: {:#x}, op: {:#x}, val: {}, timeout_ptr: {:?}", - thread::current().id(), uaddr, op, val, timeout); -// if op & OP_PRIVATE == 0 { -// unimplemented!("futex only support process-private"); -// return Err(SysError::ENOSYS); -// } + info!( + "futex: [{}] uaddr: {:#x}, op: {:#x}, val: {}, timeout_ptr: {:?}", + thread::current().id(), + uaddr, + op, + val, + timeout + ); + // if op & OP_PRIVATE == 0 { + // unimplemented!("futex only support process-private"); + // return Err(SysError::ENOSYS); + // } if uaddr % size_of::() != 0 { return Err(SysError::EINVAL); } - process().memory_set.check_mut_ptr(uaddr as *mut AtomicI32)?; + process() + .memory_set + .check_mut_ptr(uaddr as *mut AtomicI32)?; let atomic = unsafe { &mut *(uaddr as *mut AtomicI32) }; let timeout = if timeout.is_null() { None @@ -101,7 +107,7 @@ pub fn sys_futex(uaddr: usize, op: u32, val: i32, timeout: *const TimeSpec) -> S _ => { warn!("unsupported futex operation: {}", op); Err(SysError::ENOSYS) - }, + } } } @@ -119,5 +125,5 @@ pub struct SysInfo { procs: u16, totalhigh: u64, freehigh: u64, - mem_unit: u32 -} \ No newline at end of file + mem_unit: u32, +} diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index 4e79efa..86b324c 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -59,17 +59,17 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize { 035 => sys_nanosleep(args[0] as *const TimeSpec), 039 => sys_getpid(), 041 => sys_socket(args[0], args[1], args[2]), - 042 => sys_connect(args[0], args[1] as *const SockaddrIn, args[2]), - 043 => sys_accept(args[0], args[1] as *mut SockaddrIn, args[2] as *mut u32), - 044 => sys_sendto(args[0], args[1] as *const u8, args[2], args[3], args[4] as *const SockaddrIn, args[5]), - 045 => sys_recvfrom(args[0], args[1] as *mut u8, args[2], args[3], args[4] as *mut SockaddrIn, args[5] as *mut u32), + 042 => sys_connect(args[0], args[1] as *const SockAddr, args[2]), + 043 => sys_accept(args[0], args[1] as *mut SockAddr, args[2] as *mut u32), + 044 => sys_sendto(args[0], args[1] as *const u8, args[2], args[3], args[4] as *const SockAddr, args[5]), + 045 => sys_recvfrom(args[0], args[1] as *mut u8, args[2], args[3], args[4] as *mut SockAddr, args[5] as *mut u32), // 046 => sys_sendmsg(), // 047 => sys_recvmsg(), 048 => sys_shutdown(args[0], args[1]), - 049 => sys_bind(args[0], args[1] as *const SockaddrIn, args[2]), + 049 => sys_bind(args[0], args[1] as *const SockAddr, args[2]), 050 => sys_listen(args[0], args[1]), - 051 => sys_getsockname(args[0], args[1] as *mut SockaddrIn, args[2] as *mut u32), - 052 => sys_getpeername(args[0], args[1] as *mut SockaddrIn, args[2] as *mut u32), + 051 => sys_getsockname(args[0], args[1] as *mut SockAddr, args[2] as *mut u32), + 052 => sys_getpeername(args[0], args[1] as *mut SockAddr, args[2] as *mut u32), 054 => sys_setsockopt(args[0], args[1], args[2], args[3] as *const u8, args[4]), 055 => sys_getsockopt(args[0], args[1], args[2], args[3] as *mut u8, args[4] as *mut u32), 056 => sys_clone(args[0], args[1], args[2] as *mut u32, args[3] as *mut u32, args[4], tf), @@ -109,7 +109,7 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize { 204 => sys_sched_getaffinity(args[0], args[1], args[2] as *mut u32), 217 => sys_getdents64(args[0], args[1] as *mut LinuxDirent64, args[2]), 228 => sys_clock_gettime(args[0], args[1] as *mut TimeSpec), - 288 => sys_accept(args[0], args[1] as *mut SockaddrIn, args[2] as *mut u32), // use accept for accept4 + 288 => sys_accept(args[0], args[1] as *mut SockAddr, args[2] as *mut u32), // use accept for accept4 // 293 => sys_pipe(), // for musl: empty impl diff --git a/kernel/src/syscall/net.rs b/kernel/src/syscall/net.rs index 2099274..e184f42 100644 --- a/kernel/src/syscall/net.rs +++ b/kernel/src/syscall/net.rs @@ -3,6 +3,7 @@ use super::*; use crate::drivers::{NET_DRIVERS, SOCKET_ACTIVITY}; use crate::process::structs::TcpSocketState; +use core::cmp::min; use core::mem::size_of; use smoltcp::socket::*; use smoltcp::wire::*; @@ -159,18 +160,15 @@ impl Process { } } -pub fn sys_connect(fd: usize, addr: *const SockaddrIn, addrlen: usize) -> SysResult { +pub fn sys_connect(fd: usize, addr: *const SockAddr, addr_len: usize) -> SysResult { info!( - "sys_connect: fd: {}, addr: {:?}, addrlen: {}", - fd, addr, addrlen + "sys_connect: fd: {}, addr: {:?}, addr_len: {}", + fd, addr, addr_len ); let mut proc = process(); - proc.memory_set.check_ptr(addr)?; - // FIXME: check size as per sin_family - let sockaddr_in = unsafe { &*(addr) }; - let endpoint = sockaddr_in.to_endpoint()?; + let endpoint = sockaddr_to_endpoint(&mut proc, addr, addr_len)?; let wrapper = proc.get_socket(fd)?; if let SocketType::Tcp(_) = wrapper.socket_type { @@ -192,7 +190,7 @@ pub fn sys_connect(fd: usize, addr: *const SockaddrIn, addrlen: usize) -> SysRes iface.poll(); let mut sockets = iface.sockets(); - let mut socket = sockets.get::(wrapper.handle); + let socket = sockets.get::(wrapper.handle); if socket.state() == TcpState::SynSent { // still connecting drop(socket); @@ -308,7 +306,7 @@ pub fn sys_sendto( buffer: *const u8, len: usize, flags: usize, - addr: *const SockaddrIn, + addr: *const SockAddr, addr_len: usize, ) -> SysResult { info!( @@ -317,11 +315,9 @@ pub fn sys_sendto( ); let mut proc = process(); - proc.memory_set.check_ptr(addr)?; proc.memory_set.check_array(buffer, len)?; - let sockaddr_in = unsafe { &*(addr) }; - let endpoint = sockaddr_in.to_endpoint()?; + let endpoint = sockaddr_to_endpoint(&mut proc, addr, addr_len)?; let iface = &*(NET_DRIVERS.read()[0]); @@ -389,7 +385,7 @@ pub fn sys_recvfrom( buffer: *mut u8, len: usize, flags: usize, - addr: *mut SockaddrIn, + addr: *mut SockAddr, addr_len: *mut u32, ) -> SysResult { info!( @@ -404,7 +400,7 @@ pub fn sys_recvfrom( proc.memory_set.check_mut_ptr(addr_len)?; let max_addr_len = unsafe { *addr_len } as usize; - if max_addr_len < size_of::() { + if max_addr_len < size_of::() { return Err(SysError::EINVAL); } @@ -423,16 +419,16 @@ pub fn sys_recvfrom( let mut slice = unsafe { slice::from_raw_parts_mut(buffer, len) }; if let Ok(size) = socket.recv_slice(&mut slice) { - let mut packet = Ipv4Packet::new_unchecked(&slice); + let packet = Ipv4Packet::new_unchecked(&slice); if !addr.is_null() { // FIXME: check size as per sin_family - let sockaddr_in = SockaddrIn::from(IpEndpoint { + let sockaddr_in = SockAddr::from(IpEndpoint { addr: IpAddress::Ipv4(packet.src_addr()), port: 0, }); unsafe { - sockaddr_in.write_to(addr, addr_len); + sockaddr_in.write_to(&mut proc, addr, addr_len)?; } } @@ -452,9 +448,9 @@ pub fn sys_recvfrom( let mut slice = unsafe { slice::from_raw_parts_mut(buffer, len) }; if let Ok((size, endpoint)) = socket.recv_slice(&mut slice) { if !addr.is_null() { - let sockaddr_in = SockaddrIn::from(endpoint); + let sockaddr_in = SockAddr::from(endpoint); unsafe { - sockaddr_in.write_to(addr, addr_len); + sockaddr_in.write_to(&mut proc, addr, addr_len)?; } } @@ -474,9 +470,9 @@ pub fn sys_recvfrom( let mut slice = unsafe { slice::from_raw_parts_mut(buffer, len) }; if let Ok(size) = socket.recv_slice(&mut slice) { if !addr.is_null() { - let sockaddr_in = SockaddrIn::from(socket.remote_endpoint()); + let sockaddr_in = SockAddr::from(socket.remote_endpoint()); unsafe { - sockaddr_in.write_to(addr, addr_len); + sockaddr_in.write_to(&mut proc, addr, addr_len)?; } } @@ -519,16 +515,11 @@ impl Drop for SocketWrapper { } } -pub fn sys_bind(fd: usize, addr: *const SockaddrIn, len: usize) -> SysResult { - info!("sys_bind: fd: {} addr: {:?} len: {}", fd, addr, len); +pub fn sys_bind(fd: usize, addr: *const SockAddr, addr_len: usize) -> SysResult { + info!("sys_bind: fd: {} addr: {:?} len: {}", fd, addr, addr_len); let mut proc = process(); - if len < size_of::() { - return Err(SysError::EINVAL); - } - - let sockaddr_in = unsafe { &*(addr) }; - let mut endpoint = sockaddr_in.to_endpoint()?; + let mut endpoint = sockaddr_to_endpoint(&mut proc, addr, addr_len)?; if endpoint.port == 0 { endpoint.port = get_ephemeral_port(); } @@ -598,7 +589,7 @@ pub fn sys_shutdown(fd: usize, how: usize) -> SysResult { } } -pub fn sys_accept(fd: usize, addr: *mut SockaddrIn, addr_len: *mut u32) -> SysResult { +pub fn sys_accept(fd: usize, addr: *mut SockAddr, addr_len: *mut u32) -> SysResult { info!( "sys_accept: fd: {} addr: {:?} addr_len: {:?}", fd, addr, addr_len @@ -611,7 +602,7 @@ pub fn sys_accept(fd: usize, addr: *mut SockaddrIn, addr_len: *mut u32) -> SysRe proc.memory_set.check_mut_ptr(addr_len)?; let max_addr_len = unsafe { *addr_len } as usize; - if max_addr_len < size_of::() { + if max_addr_len < size_of::() { debug!("length too short {}", max_addr_len); return Err(SysError::EINVAL); } @@ -625,7 +616,7 @@ pub fn sys_accept(fd: usize, addr: *mut SockaddrIn, addr_len: *mut u32) -> SysRe loop { let iface = &*(NET_DRIVERS.read()[0]); let mut sockets = iface.sockets(); - let mut socket = sockets.get::(wrapper.handle); + let socket = sockets.get::(wrapper.handle); if socket.is_active() { let remote_endpoint = socket.remote_endpoint(); @@ -665,9 +656,9 @@ pub fn sys_accept(fd: usize, addr: *mut SockaddrIn, addr_len: *mut u32) -> SysRe proc.files.insert(new_fd, orig_socket); if !addr.is_null() { - let sockaddr_in = SockaddrIn::from(remote_endpoint); + let sockaddr_in = SockAddr::from(remote_endpoint); unsafe { - sockaddr_in.write_to(addr, addr_len); + sockaddr_in.write_to(&mut proc, addr, addr_len)?; } } return Ok(new_fd); @@ -688,7 +679,7 @@ pub fn sys_accept(fd: usize, addr: *mut SockaddrIn, addr_len: *mut u32) -> SysRe } } -pub fn sys_getsockname(fd: usize, addr: *mut SockaddrIn, addr_len: *mut u32) -> SysResult { +pub fn sys_getsockname(fd: usize, addr: *mut SockAddr, addr_len: *mut u32) -> SysResult { info!( "sys_getsockname: fd: {} addr: {:?} addr_len: {:?}", fd, addr, addr_len @@ -705,7 +696,7 @@ pub fn sys_getsockname(fd: usize, addr: *mut SockaddrIn, addr_len: *mut u32) -> proc.memory_set.check_mut_ptr(addr_len)?; let max_addr_len = unsafe { *addr_len } as usize; - if max_addr_len < size_of::() { + if max_addr_len < size_of::() { return Err(SysError::EINVAL); } @@ -715,9 +706,9 @@ pub fn sys_getsockname(fd: usize, addr: *mut SockaddrIn, addr_len: *mut u32) -> let wrapper = proc.get_socket_mut(fd)?; if let SocketType::Tcp(state) = &wrapper.socket_type { if let Some(endpoint) = state.local_endpoint { - let sockaddr_in = SockaddrIn::from(endpoint); + let sockaddr_in = SockAddr::from(endpoint); unsafe { - sockaddr_in.write_to(addr, addr_len); + sockaddr_in.write_to(&mut proc, addr, addr_len)?; } Ok(0) } else { @@ -728,7 +719,7 @@ pub fn sys_getsockname(fd: usize, addr: *mut SockaddrIn, addr_len: *mut u32) -> } } -pub fn sys_getpeername(fd: usize, addr: *mut SockaddrIn, addr_len: *mut u32) -> SysResult { +pub fn sys_getpeername(fd: usize, addr: *mut SockAddr, addr_len: *mut u32) -> SysResult { info!( "sys_getpeername: fd: {} addr: {:?} addr_len: {:?}", fd, addr, addr_len @@ -745,7 +736,7 @@ pub fn sys_getpeername(fd: usize, addr: *mut SockaddrIn, addr_len: *mut u32) -> proc.memory_set.check_mut_ptr(addr_len)?; let max_addr_len = unsafe { *addr_len } as usize; - if max_addr_len < size_of::() { + if max_addr_len < size_of::() { return Err(SysError::EINVAL); } @@ -759,9 +750,9 @@ pub fn sys_getpeername(fd: usize, addr: *mut SockaddrIn, addr_len: *mut u32) -> if socket.is_open() { let remote_endpoint = socket.remote_endpoint(); - let sockaddr_in = SockaddrIn::from(remote_endpoint); + let sockaddr_in = SockAddr::from(remote_endpoint); unsafe { - sockaddr_in.write_to(addr, addr_len); + sockaddr_in.write_to(&mut proc, addr, addr_len)?; } Ok(0) } else { @@ -781,7 +772,7 @@ pub fn poll_socket(wrapper: &SocketWrapper) -> (bool, bool, bool) { if let SocketType::Tcp(state) = wrapper.socket_type.clone() { let iface = &*(NET_DRIVERS.read()[0]); let mut sockets = iface.sockets(); - let mut socket = sockets.get::(wrapper.handle); + let socket = sockets.get::(wrapper.handle); if state.is_listening && socket.is_active() { // a new connection @@ -805,55 +796,115 @@ pub fn poll_socket(wrapper: &SocketWrapper) -> (bool, bool, bool) { } pub fn sys_dup2_socket(proc: &mut Process, wrapper: SocketWrapper, fd: usize) -> SysResult { - let iface = &*(NET_DRIVERS.read()[0]); - let mut sockets = iface.sockets(); - sockets.retain(wrapper.handle); proc.files.insert(fd, FileLike::Socket(wrapper)); Ok(fd) } #[repr(C)] -pub struct SockaddrIn { +pub struct SockAddrIn { sin_family: u16, sin_port: u16, sin_addr: u32, sin_zero: [u8; 8], } -impl From for SockaddrIn { +#[repr(C)] +pub struct SockAddrUn { + sun_family: u16, + sun_path: [u8; 108], +} + +#[repr(C)] +pub union SockAddrPayload { + addr_in: SockAddrIn, + addr_un: SockAddrUn, +} + +#[repr(C)] +pub struct SockAddr { + family: u16, + payload: SockAddrPayload, +} + +impl From for SockAddr { fn from(endpoint: IpEndpoint) -> Self { match endpoint.addr { - IpAddress::Ipv4(ipv4) => SockaddrIn { - sin_family: AF_INET as u16, - sin_port: u16::to_be(endpoint.port), - sin_addr: u32::to_be(u32::from_be_bytes(ipv4.0)), - sin_zero: [0; 8], + IpAddress::Ipv4(ipv4) => SockAddr { + family: AF_INET as u16, + payload: SockAddrPayload { + addr_in: SockAddrIn { + sin_family: AF_INET as u16, + sin_port: u16::to_be(endpoint.port), + sin_addr: u32::to_be(u32::from_be_bytes(ipv4.0)), + sin_zero: [0; 8], + }, + }, }, _ => unimplemented!("ipv6"), } } } -impl SockaddrIn { - fn to_endpoint(&self) -> Result { - // FIXME: check size as per sin_family - if self.sin_family == AF_INET as u16 { - let port = u16::from_be(self.sin_port); - let addr = IpAddress::from(Ipv4Address::from_bytes( - &u32::from_be(self.sin_addr).to_be_bytes()[..], - )); - Ok((addr, port).into()) - } else if self.sin_family == AF_UNIX as u16 { - debug!("unix socket path {}", unsafe { - util::from_cstr((self as *const SockaddrIn as *const u8).add(2)) - }); - Err(SysError::EINVAL) - } else { - Err(SysError::EINVAL) +/// Convert sockaddr to endpoint +// Check len is long enough +fn sockaddr_to_endpoint( + proc: &mut Process, + addr: *const SockAddr, + len: usize, +) -> Result { + if len < size_of::() { + return Err(SysError::EINVAL); + } + proc.memory_set.check_array(addr as *const u8, len)?; + unsafe { + match (*addr).family as usize { + AF_INET => { + if len < size_of::() + size_of::() { + return Err(SysError::EINVAL); + } + let port = u16::from_be((*addr).payload.addr_in.sin_port); + let addr = IpAddress::from(Ipv4Address::from_bytes( + &u32::from_be((*addr).payload.addr_in.sin_addr).to_be_bytes()[..], + )); + Ok((addr, port).into()) + } + AF_UNIX => Err(SysError::EINVAL), + _ => Err(SysError::EINVAL), } } - unsafe fn write_to(self, addr: *mut SockaddrIn, addr_len: *mut u32) { - addr.write(self); - addr_len.write(size_of::() as u32); +} + +impl SockAddr { + /// Write to user sockaddr + /// Check mutability for user + unsafe fn write_to( + self, + proc: &mut Process, + addr: *mut SockAddr, + addr_len: *mut u32, + ) -> SysResult { + // Ignore NULL + if addr.is_null() { + return Ok(0); + } + + proc.memory_set.check_mut_ptr(addr_len)?; + let max_addr_len = *addr_len as usize; + let full_len = match self.family as usize { + AF_INET => size_of::() + size_of::(), + AF_UNIX => return Err(SysError::EINVAL), + _ => return Err(SysError::EINVAL), + }; + + let written_len = min(max_addr_len, full_len); + if written_len > 0 { + proc.memory_set + .check_mut_array(addr as *mut u8, written_len)?; + let source = slice::from_raw_parts(&self as *const SockAddr as *const u8, written_len); + let target = slice::from_raw_parts_mut(addr as *mut u8, written_len); + target.copy_from_slice(source); + } + addr_len.write(full_len as u32); + return Ok(0); } } diff --git a/kernel/src/syscall/time.rs b/kernel/src/syscall/time.rs index 9249c70..0f51241 100644 --- a/kernel/src/syscall/time.rs +++ b/kernel/src/syscall/time.rs @@ -47,7 +47,7 @@ pub fn sys_gettimeofday(tv: *mut TimeVal, tz: *const u8) -> SysResult { return Err(SysError::EINVAL); } - let mut proc = process(); + let proc = process(); proc.memory_set.check_mut_ptr(tv)?; let tick_base = *TICK_BASE; @@ -69,7 +69,7 @@ pub fn sys_gettimeofday(tv: *mut TimeVal, tz: *const u8) -> SysResult { pub fn sys_clock_gettime(clock: usize, ts: *mut TimeSpec) -> SysResult { info!("clock_gettime: clock: {:?}, ts: {:?}", clock, ts); - let mut proc = process(); + let proc = process(); proc.memory_set.check_mut_ptr(ts)?; let tick_base = *TICK_BASE; @@ -96,7 +96,7 @@ pub fn sys_time(time: *mut u64) -> SysResult { let usec = (tick - tick_base) * USEC_PER_TICK as u64; let sec = epoch_base + usec / 1_000_000; if time as usize != 0 { - let mut proc = process(); + let proc = process(); proc.memory_set.check_mut_ptr(time)?; unsafe { time.write(sec as u64);