Use union to implement sockaddr, and eliminate many warnings

master
Jiajie Chen 6 years ago
parent d041884cc2
commit cb0a51d28d

@ -279,7 +279,7 @@ impl Process {
fn memory_set_from(elf: &ElfFile<'_>) -> (MemorySet, usize) { fn memory_set_from(elf: &ElfFile<'_>) -> (MemorySet, usize) {
debug!("creating MemorySet from ELF"); debug!("creating MemorySet from ELF");
let mut ms = MemorySet::new(); 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 // [NoMMU] Get total memory size and alloc space
let va_begin = elf.program_iter() let va_begin = elf.program_iter()

@ -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 { pub fn sys_poll(ufds: *mut PollFd, nfds: usize, timeout_msecs: usize) -> SysResult {
info!("poll: ufds: {:?}, nfds: {}, timeout_msecs: {:#x}", ufds, nfds, timeout_msecs); 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)?; proc.memory_set.check_mut_array(ufds, nfds)?;
let polls = unsafe { slice::from_raw_parts_mut(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(); let begin_time_ms = crate::trap::uptime_msec();
loop { loop {
use PollEvents as PE; use PollEvents as PE;
let mut proc = process(); let proc = process();
let mut events = 0; let mut events = 0;
for poll in polls.iter_mut() { for poll in polls.iter_mut() {
poll.revents = PE::NONE; 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 { 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); 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 read_fds = FdSet::new(&proc, read, nfds)?;
let mut write_fds = FdSet::new(&proc, write, nfds)?; let mut write_fds = FdSet::new(&proc, write, nfds)?;
let mut err_fds = FdSet::new(&proc, err, 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(); let begin_time_ms = crate::trap::uptime_msec();
loop { loop {
let mut proc = process(); let proc = process();
let mut events = 0; let mut events = 0;
for (fd, file) in proc.files.iter() { for (fd, file) in proc.files.iter() {
if *fd < nfds { 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 { pub fn sys_getcwd(buf: *mut u8, len: usize) -> SysResult {
info!("getcwd: buf: {:?}, len: {:#x}", buf, len); info!("getcwd: buf: {:?}, len: {:#x}", buf, len);
let mut proc = process(); let proc = process();
proc.memory_set.check_mut_array(buf, len)?; proc.memory_set.check_mut_array(buf, len)?;
if proc.cwd.len() + 1 > len { if proc.cwd.len() + 1 > len {
return Err(SysError::ERANGE); 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 { 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)? }; let path = unsafe { proc.memory_set.check_and_clone_cstr(path)? };
proc.memory_set.check_mut_ptr(stat_ptr)?; proc.memory_set.check_mut_ptr(stat_ptr)?;
info!("lstat: path: {}", path); 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 { 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)? }; let path = unsafe { proc.memory_set.check_and_clone_cstr(path)? };
info!("truncate: path: {:?}, len: {}", path, len); info!("truncate: path: {:?}, len: {}", path, len);
proc.lookup_inode(&path)?.resize(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 { 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 oldpath = unsafe { proc.memory_set.check_and_clone_cstr(oldpath)? };
let newpath = unsafe { proc.memory_set.check_and_clone_cstr(newpath)? }; let newpath = unsafe { proc.memory_set.check_and_clone_cstr(newpath)? };
info!("rename: oldpath: {:?}, newpath: {:?}", oldpath, 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 { 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)? }; let path = unsafe { proc.memory_set.check_and_clone_cstr(path)? };
// TODO: check pathname // TODO: check pathname
info!("mkdir: path: {:?}, mode: {:#o}", path, mode); 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 { 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 oldpath = unsafe { proc.memory_set.check_and_clone_cstr(oldpath)? };
let newpath = unsafe { proc.memory_set.check_and_clone_cstr(newpath)? }; let newpath = unsafe { proc.memory_set.check_and_clone_cstr(newpath)? };
info!("link: oldpath: {:?}, newpath: {:?}", oldpath, 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 { 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)? }; let path = unsafe { proc.memory_set.check_and_clone_cstr(path)? };
info!("unlink: path: {:?}", path); info!("unlink: path: {:?}", path);

@ -8,10 +8,20 @@ use crate::memory::GlobalFrameAlloc;
use super::*; 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 prot = MmapProt::from_bits_truncate(prot);
let flags = MmapFlags::from_bits_truncate(flags); 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(); let mut proc = process();
if addr == 0 { 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) { if flags.contains(MmapFlags::SHARED) {
return Err(SysError::EINVAL); 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); return Ok(addr);
} }
unimplemented!() 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 { pub fn sys_mprotect(addr: usize, len: usize, prot: usize) -> SysResult {
let prot = MmapProt::from_bits_truncate(prot); 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 mut proc = process();
let attr = prot.to_attr(); 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| { proc.memory_set.edit(|pt| {
for page in Page::range_of(addr, addr + len) { 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); attr.apply(entry);
} }
}); });
@ -96,7 +117,9 @@ bitflags! {
impl MmapProt { impl MmapProt {
fn to_attr(self) -> MemoryAttr { fn to_attr(self) -> MemoryAttr {
let mut attr = MemoryAttr::default().user(); 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 // FIXME: see sys_mprotect
// if !self.contains(MmapProt::WRITE) { attr = attr.readonly(); } // if !self.contains(MmapProt::WRITE) { attr = attr.readonly(); }
attr attr

@ -54,15 +54,19 @@ pub fn sys_sysinfo(sys_info: *mut SysInfo) -> SysResult {
proc.memory_set.check_mut_ptr(sys_info)?; proc.memory_set.check_mut_ptr(sys_info)?;
let sysinfo = SysInfo::default(); let sysinfo = SysInfo::default();
unsafe { unsafe { *sys_info = sysinfo };
*sys_info = sysinfo
};
Ok(0) Ok(0)
} }
pub fn sys_futex(uaddr: usize, op: u32, val: i32, timeout: *const TimeSpec) -> SysResult { pub fn sys_futex(uaddr: usize, op: u32, val: i32, timeout: *const TimeSpec) -> SysResult {
info!("futex: [{}] uaddr: {:#x}, op: {:#x}, val: {}, timeout_ptr: {:?}", info!(
thread::current().id(), uaddr, op, val, timeout); "futex: [{}] uaddr: {:#x}, op: {:#x}, val: {}, timeout_ptr: {:?}",
thread::current().id(),
uaddr,
op,
val,
timeout
);
// if op & OP_PRIVATE == 0 { // if op & OP_PRIVATE == 0 {
// unimplemented!("futex only support process-private"); // unimplemented!("futex only support process-private");
// return Err(SysError::ENOSYS); // return Err(SysError::ENOSYS);
@ -70,7 +74,9 @@ pub fn sys_futex(uaddr: usize, op: u32, val: i32, timeout: *const TimeSpec) -> S
if uaddr % size_of::<u32>() != 0 { if uaddr % size_of::<u32>() != 0 {
return Err(SysError::EINVAL); 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 atomic = unsafe { &mut *(uaddr as *mut AtomicI32) };
let timeout = if timeout.is_null() { let timeout = if timeout.is_null() {
None None
@ -101,7 +107,7 @@ pub fn sys_futex(uaddr: usize, op: u32, val: i32, timeout: *const TimeSpec) -> S
_ => { _ => {
warn!("unsupported futex operation: {}", op); warn!("unsupported futex operation: {}", op);
Err(SysError::ENOSYS) Err(SysError::ENOSYS)
}, }
} }
} }
@ -119,5 +125,5 @@ pub struct SysInfo {
procs: u16, procs: u16,
totalhigh: u64, totalhigh: u64,
freehigh: u64, freehigh: u64,
mem_unit: u32 mem_unit: u32,
} }

@ -59,17 +59,17 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize {
035 => sys_nanosleep(args[0] as *const TimeSpec), 035 => sys_nanosleep(args[0] as *const TimeSpec),
039 => sys_getpid(), 039 => sys_getpid(),
041 => sys_socket(args[0], args[1], args[2]), 041 => sys_socket(args[0], args[1], args[2]),
042 => sys_connect(args[0], args[1] as *const SockaddrIn, args[2]), 042 => sys_connect(args[0], args[1] as *const SockAddr, args[2]),
043 => sys_accept(args[0], args[1] as *mut SockaddrIn, args[2] as *mut u32), 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 SockaddrIn, args[5]), 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 SockaddrIn, args[5] as *mut u32), 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(), // 046 => sys_sendmsg(),
// 047 => sys_recvmsg(), // 047 => sys_recvmsg(),
048 => sys_shutdown(args[0], args[1]), 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]), 050 => sys_listen(args[0], args[1]),
051 => sys_getsockname(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 SockaddrIn, 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]), 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), 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), 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), 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]), 217 => sys_getdents64(args[0], args[1] as *mut LinuxDirent64, args[2]),
228 => sys_clock_gettime(args[0], args[1] as *mut TimeSpec), 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(), // 293 => sys_pipe(),
// for musl: empty impl // for musl: empty impl

@ -3,6 +3,7 @@
use super::*; use super::*;
use crate::drivers::{NET_DRIVERS, SOCKET_ACTIVITY}; use crate::drivers::{NET_DRIVERS, SOCKET_ACTIVITY};
use crate::process::structs::TcpSocketState; use crate::process::structs::TcpSocketState;
use core::cmp::min;
use core::mem::size_of; use core::mem::size_of;
use smoltcp::socket::*; use smoltcp::socket::*;
use smoltcp::wire::*; 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!( info!(
"sys_connect: fd: {}, addr: {:?}, addrlen: {}", "sys_connect: fd: {}, addr: {:?}, addr_len: {}",
fd, addr, addrlen fd, addr, addr_len
); );
let mut proc = process(); let mut proc = process();
proc.memory_set.check_ptr(addr)?;
// FIXME: check size as per sin_family let endpoint = sockaddr_to_endpoint(&mut proc, addr, addr_len)?;
let sockaddr_in = unsafe { &*(addr) };
let endpoint = sockaddr_in.to_endpoint()?;
let wrapper = proc.get_socket(fd)?; let wrapper = proc.get_socket(fd)?;
if let SocketType::Tcp(_) = wrapper.socket_type { 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(); iface.poll();
let mut sockets = iface.sockets(); let mut sockets = iface.sockets();
let mut socket = sockets.get::<TcpSocket>(wrapper.handle); let socket = sockets.get::<TcpSocket>(wrapper.handle);
if socket.state() == TcpState::SynSent { if socket.state() == TcpState::SynSent {
// still connecting // still connecting
drop(socket); drop(socket);
@ -308,7 +306,7 @@ pub fn sys_sendto(
buffer: *const u8, buffer: *const u8,
len: usize, len: usize,
flags: usize, flags: usize,
addr: *const SockaddrIn, addr: *const SockAddr,
addr_len: usize, addr_len: usize,
) -> SysResult { ) -> SysResult {
info!( info!(
@ -317,11 +315,9 @@ pub fn sys_sendto(
); );
let mut proc = process(); let mut proc = process();
proc.memory_set.check_ptr(addr)?;
proc.memory_set.check_array(buffer, len)?; proc.memory_set.check_array(buffer, len)?;
let sockaddr_in = unsafe { &*(addr) }; let endpoint = sockaddr_to_endpoint(&mut proc, addr, addr_len)?;
let endpoint = sockaddr_in.to_endpoint()?;
let iface = &*(NET_DRIVERS.read()[0]); let iface = &*(NET_DRIVERS.read()[0]);
@ -389,7 +385,7 @@ pub fn sys_recvfrom(
buffer: *mut u8, buffer: *mut u8,
len: usize, len: usize,
flags: usize, flags: usize,
addr: *mut SockaddrIn, addr: *mut SockAddr,
addr_len: *mut u32, addr_len: *mut u32,
) -> SysResult { ) -> SysResult {
info!( info!(
@ -404,7 +400,7 @@ pub fn sys_recvfrom(
proc.memory_set.check_mut_ptr(addr_len)?; proc.memory_set.check_mut_ptr(addr_len)?;
let max_addr_len = unsafe { *addr_len } as usize; let max_addr_len = unsafe { *addr_len } as usize;
if max_addr_len < size_of::<SockaddrIn>() { if max_addr_len < size_of::<SockAddr>() {
return Err(SysError::EINVAL); return Err(SysError::EINVAL);
} }
@ -423,16 +419,16 @@ pub fn sys_recvfrom(
let mut slice = unsafe { slice::from_raw_parts_mut(buffer, len) }; let mut slice = unsafe { slice::from_raw_parts_mut(buffer, len) };
if let Ok(size) = socket.recv_slice(&mut slice) { 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() { if !addr.is_null() {
// FIXME: check size as per sin_family // 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()), addr: IpAddress::Ipv4(packet.src_addr()),
port: 0, port: 0,
}); });
unsafe { 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) }; let mut slice = unsafe { slice::from_raw_parts_mut(buffer, len) };
if let Ok((size, endpoint)) = socket.recv_slice(&mut slice) { if let Ok((size, endpoint)) = socket.recv_slice(&mut slice) {
if !addr.is_null() { if !addr.is_null() {
let sockaddr_in = SockaddrIn::from(endpoint); let sockaddr_in = SockAddr::from(endpoint);
unsafe { 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) }; let mut slice = unsafe { slice::from_raw_parts_mut(buffer, len) };
if let Ok(size) = socket.recv_slice(&mut slice) { if let Ok(size) = socket.recv_slice(&mut slice) {
if !addr.is_null() { if !addr.is_null() {
let sockaddr_in = SockaddrIn::from(socket.remote_endpoint()); let sockaddr_in = SockAddr::from(socket.remote_endpoint());
unsafe { 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 { pub fn sys_bind(fd: usize, addr: *const SockAddr, addr_len: usize) -> SysResult {
info!("sys_bind: fd: {} addr: {:?} len: {}", fd, addr, len); info!("sys_bind: fd: {} addr: {:?} len: {}", fd, addr, addr_len);
let mut proc = process(); let mut proc = process();
if len < size_of::<SockaddrIn>() { let mut endpoint = sockaddr_to_endpoint(&mut proc, addr, addr_len)?;
return Err(SysError::EINVAL);
}
let sockaddr_in = unsafe { &*(addr) };
let mut endpoint = sockaddr_in.to_endpoint()?;
if endpoint.port == 0 { if endpoint.port == 0 {
endpoint.port = get_ephemeral_port(); 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!( info!(
"sys_accept: fd: {} addr: {:?} addr_len: {:?}", "sys_accept: fd: {} addr: {:?} addr_len: {:?}",
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)?; proc.memory_set.check_mut_ptr(addr_len)?;
let max_addr_len = unsafe { *addr_len } as usize; let max_addr_len = unsafe { *addr_len } as usize;
if max_addr_len < size_of::<SockaddrIn>() { if max_addr_len < size_of::<SockAddr>() {
debug!("length too short {}", max_addr_len); debug!("length too short {}", max_addr_len);
return Err(SysError::EINVAL); return Err(SysError::EINVAL);
} }
@ -625,7 +616,7 @@ pub fn sys_accept(fd: usize, addr: *mut SockaddrIn, addr_len: *mut u32) -> SysRe
loop { loop {
let iface = &*(NET_DRIVERS.read()[0]); let iface = &*(NET_DRIVERS.read()[0]);
let mut sockets = iface.sockets(); let mut sockets = iface.sockets();
let mut socket = sockets.get::<TcpSocket>(wrapper.handle); let socket = sockets.get::<TcpSocket>(wrapper.handle);
if socket.is_active() { if socket.is_active() {
let remote_endpoint = socket.remote_endpoint(); 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); proc.files.insert(new_fd, orig_socket);
if !addr.is_null() { if !addr.is_null() {
let sockaddr_in = SockaddrIn::from(remote_endpoint); let sockaddr_in = SockAddr::from(remote_endpoint);
unsafe { unsafe {
sockaddr_in.write_to(addr, addr_len); sockaddr_in.write_to(&mut proc, addr, addr_len)?;
} }
} }
return Ok(new_fd); 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!( info!(
"sys_getsockname: fd: {} addr: {:?} addr_len: {:?}", "sys_getsockname: fd: {} addr: {:?} addr_len: {:?}",
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)?; proc.memory_set.check_mut_ptr(addr_len)?;
let max_addr_len = unsafe { *addr_len } as usize; let max_addr_len = unsafe { *addr_len } as usize;
if max_addr_len < size_of::<SockaddrIn>() { if max_addr_len < size_of::<SockAddr>() {
return Err(SysError::EINVAL); 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)?; let wrapper = proc.get_socket_mut(fd)?;
if let SocketType::Tcp(state) = &wrapper.socket_type { if let SocketType::Tcp(state) = &wrapper.socket_type {
if let Some(endpoint) = state.local_endpoint { if let Some(endpoint) = state.local_endpoint {
let sockaddr_in = SockaddrIn::from(endpoint); let sockaddr_in = SockAddr::from(endpoint);
unsafe { unsafe {
sockaddr_in.write_to(addr, addr_len); sockaddr_in.write_to(&mut proc, addr, addr_len)?;
} }
Ok(0) Ok(0)
} else { } 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!( info!(
"sys_getpeername: fd: {} addr: {:?} addr_len: {:?}", "sys_getpeername: fd: {} addr: {:?} addr_len: {:?}",
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)?; proc.memory_set.check_mut_ptr(addr_len)?;
let max_addr_len = unsafe { *addr_len } as usize; let max_addr_len = unsafe { *addr_len } as usize;
if max_addr_len < size_of::<SockaddrIn>() { if max_addr_len < size_of::<SockAddr>() {
return Err(SysError::EINVAL); 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() { if socket.is_open() {
let remote_endpoint = socket.remote_endpoint(); let remote_endpoint = socket.remote_endpoint();
let sockaddr_in = SockaddrIn::from(remote_endpoint); let sockaddr_in = SockAddr::from(remote_endpoint);
unsafe { unsafe {
sockaddr_in.write_to(addr, addr_len); sockaddr_in.write_to(&mut proc, addr, addr_len)?;
} }
Ok(0) Ok(0)
} else { } else {
@ -781,7 +772,7 @@ pub fn poll_socket(wrapper: &SocketWrapper) -> (bool, bool, bool) {
if let SocketType::Tcp(state) = wrapper.socket_type.clone() { if let SocketType::Tcp(state) = wrapper.socket_type.clone() {
let iface = &*(NET_DRIVERS.read()[0]); let iface = &*(NET_DRIVERS.read()[0]);
let mut sockets = iface.sockets(); let mut sockets = iface.sockets();
let mut socket = sockets.get::<TcpSocket>(wrapper.handle); let socket = sockets.get::<TcpSocket>(wrapper.handle);
if state.is_listening && socket.is_active() { if state.is_listening && socket.is_active() {
// a new connection // 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 { 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)); proc.files.insert(fd, FileLike::Socket(wrapper));
Ok(fd) Ok(fd)
} }
#[repr(C)] #[repr(C)]
pub struct SockaddrIn { pub struct SockAddrIn {
sin_family: u16, sin_family: u16,
sin_port: u16, sin_port: u16,
sin_addr: u32, sin_addr: u32,
sin_zero: [u8; 8], sin_zero: [u8; 8],
} }
impl From<IpEndpoint> 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<IpEndpoint> for SockAddr {
fn from(endpoint: IpEndpoint) -> Self { fn from(endpoint: IpEndpoint) -> Self {
match endpoint.addr { match endpoint.addr {
IpAddress::Ipv4(ipv4) => SockaddrIn { IpAddress::Ipv4(ipv4) => SockAddr {
family: AF_INET as u16,
payload: SockAddrPayload {
addr_in: SockAddrIn {
sin_family: AF_INET as u16, sin_family: AF_INET as u16,
sin_port: u16::to_be(endpoint.port), sin_port: u16::to_be(endpoint.port),
sin_addr: u32::to_be(u32::from_be_bytes(ipv4.0)), sin_addr: u32::to_be(u32::from_be_bytes(ipv4.0)),
sin_zero: [0; 8], sin_zero: [0; 8],
}, },
},
},
_ => unimplemented!("ipv6"), _ => unimplemented!("ipv6"),
} }
} }
} }
impl SockaddrIn { /// Convert sockaddr to endpoint
fn to_endpoint(&self) -> Result<IpEndpoint, SysError> { // Check len is long enough
// FIXME: check size as per sin_family fn sockaddr_to_endpoint(
if self.sin_family == AF_INET as u16 { proc: &mut Process,
let port = u16::from_be(self.sin_port); addr: *const SockAddr,
len: usize,
) -> Result<IpEndpoint, SysError> {
if len < size_of::<u16>() {
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::<u16>() + size_of::<SockAddrIn>() {
return Err(SysError::EINVAL);
}
let port = u16::from_be((*addr).payload.addr_in.sin_port);
let addr = IpAddress::from(Ipv4Address::from_bytes( let addr = IpAddress::from(Ipv4Address::from_bytes(
&u32::from_be(self.sin_addr).to_be_bytes()[..], &u32::from_be((*addr).payload.addr_in.sin_addr).to_be_bytes()[..],
)); ));
Ok((addr, port).into()) Ok((addr, port).into())
} else if self.sin_family == AF_UNIX as u16 { }
debug!("unix socket path {}", unsafe { AF_UNIX => Err(SysError::EINVAL),
util::from_cstr((self as *const SockaddrIn as *const u8).add(2)) _ => Err(SysError::EINVAL),
});
Err(SysError::EINVAL)
} else {
Err(SysError::EINVAL)
} }
} }
unsafe fn write_to(self, addr: *mut SockaddrIn, addr_len: *mut u32) { }
addr.write(self);
addr_len.write(size_of::<SockaddrIn>() 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::<u16>() + size_of::<SockAddrIn>(),
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);
} }
} }

@ -47,7 +47,7 @@ pub fn sys_gettimeofday(tv: *mut TimeVal, tz: *const u8) -> SysResult {
return Err(SysError::EINVAL); return Err(SysError::EINVAL);
} }
let mut proc = process(); let proc = process();
proc.memory_set.check_mut_ptr(tv)?; proc.memory_set.check_mut_ptr(tv)?;
let tick_base = *TICK_BASE; 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 { pub fn sys_clock_gettime(clock: usize, ts: *mut TimeSpec) -> SysResult {
info!("clock_gettime: clock: {:?}, ts: {:?}", clock, ts); info!("clock_gettime: clock: {:?}, ts: {:?}", clock, ts);
let mut proc = process(); let proc = process();
proc.memory_set.check_mut_ptr(ts)?; proc.memory_set.check_mut_ptr(ts)?;
let tick_base = *TICK_BASE; 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 usec = (tick - tick_base) * USEC_PER_TICK as u64;
let sec = epoch_base + usec / 1_000_000; let sec = epoch_base + usec / 1_000_000;
if time as usize != 0 { if time as usize != 0 {
let mut proc = process(); let proc = process();
proc.memory_set.check_mut_ptr(time)?; proc.memory_set.check_mut_ptr(time)?;
unsafe { unsafe {
time.write(sec as u64); time.write(sec as u64);

Loading…
Cancel
Save