From 8090e154c171d4cfabc9b585f1f950d309a6bcd9 Mon Sep 17 00:00:00 2001 From: WangRunji Date: Fri, 19 Apr 2019 12:43:05 +0800 Subject: [PATCH] simplify sys_sendfile. check elf arch --- kernel/src/process/structs.rs | 18 +++++-- kernel/src/syscall/fs.rs | 95 ++++++++++++++++------------------- kernel/src/syscall/mod.rs | 8 +++ 3 files changed, 66 insertions(+), 55 deletions(-) diff --git a/kernel/src/process/structs.rs b/kernel/src/process/structs.rs index 06cb0b7..a9982ee 100644 --- a/kernel/src/process/structs.rs +++ b/kernel/src/process/structs.rs @@ -174,18 +174,30 @@ impl Thread { _ => panic!("ELF is not executable or shared object"), } - // Check interpreter + // Check ELF arch + match elf.header.pt2.machine().as_machine() { + #[cfg(target_arch = "x86_64")] + header::Machine::X86_64 => {} + #[cfg(target_arch = "aarch64")] + header::Machine::AArch64 => {} + #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] + header::Machine::Other(243) => {} + #[cfg(target_arch = "mips")] + header::Machine::Mips => {} + machine @ _ => panic!("invalid elf arch: {:?}", machine), + } + + // Check interpreter (for dynamic link) if let Ok(loader_path) = elf.get_interpreter() { // assuming absolute path if let Ok(inode) = crate::fs::ROOT_INODE.lookup_follow(loader_path, FOLLOW_MAX_DEPTH) { if let Ok(buf) = inode.read_as_vec() { - debug!("using loader {}", &loader_path); // Elf loader should not have INTERP // No infinite loop args.insert(0, loader_path.into()); args.insert(1, exec_path.into()); args.remove(2); - warn!("loader args: {:?}", args); + info!("loader args: {:?}", args); return Thread::new_user(buf.as_slice(), exec_path, args, envs); } else { warn!("loader specified as {} but failed to read", &loader_path); diff --git a/kernel/src/syscall/fs.rs b/kernel/src/syscall/fs.rs index 0025034..43d0bca 100644 --- a/kernel/src/syscall/fs.rs +++ b/kernel/src/syscall/fs.rs @@ -662,8 +662,8 @@ pub fn sys_pipe(fds: *mut u32) -> SysResult { ); unsafe { - *fds = read_fd as u32; - *(fds.add(1)) = write_fd as u32; + fds.write(read_fd as u32); + fds.add(1).write(write_fd as u32); } info!("pipe: created rfd: {} wfd: {}", read_fd, write_fd); @@ -676,69 +676,60 @@ pub fn sys_sync() -> SysResult { Ok(0) } -pub fn sys_sendfile(out_fd: usize, in_fd: usize, offset: *mut usize, count: usize) -> SysResult { +pub fn sys_sendfile( + out_fd: usize, + in_fd: usize, + offset_ptr: *mut usize, + count: usize, +) -> SysResult { info!( - "sendfile: out: {}, in: {}, offset: {:?}, count: {}", - out_fd, in_fd, offset, count + "sendfile: out: {}, in: {}, offset_ptr: {:?}, count: {}", + out_fd, in_fd, offset_ptr, count ); let proc = process(); // We know it's save, pacify the borrow checker let proc_cell = UnsafeCell::new(proc); - let proc_in = unsafe { &mut *proc_cell.get() }; - let proc_out = unsafe { &mut *proc_cell.get() }; - //let in_file: &mut FileHandle = unsafe { &mut *UnsafeCell::new(proc.get_file(in_fd)?).get() }; - //let out_file: &mut FileHandle = unsafe { &mut *UnsafeCell::new(proc.get_file(out_fd)?).get() }; - let in_file = proc_in.get_file(in_fd)?; - let out_file = proc_out.get_file(out_fd)?; + let in_file = unsafe { (*proc_cell.get()).get_file(in_fd)? }; + let out_file = unsafe { (*proc_cell.get()).get_file(out_fd)? }; let mut buffer = [0u8; 1024]; - if offset.is_null() { - // read from current file offset - let mut bytes_read = 0; - while bytes_read < count { - let len = min(buffer.len(), count - bytes_read); - let read_len = in_file.read(&mut buffer[..len])?; - if read_len == 0 { - break; - } - bytes_read += read_len; - let mut bytes_written = 0; - while bytes_written < read_len { - let write_len = out_file.write(&buffer[bytes_written..])?; - if write_len == 0 { - return Err(SysError::EBADF); - } - bytes_written += write_len; - } + + let mut read_offset = if !offset_ptr.is_null() { + unsafe { + (*proc_cell.get()).vm.check_read_ptr(offset_ptr)?; + offset_ptr.read() } - return Ok(bytes_read); } else { - let proc_mem = unsafe { &mut *proc_cell.get() }; - proc_mem.vm.check_read_ptr(offset)?; - let mut read_offset = unsafe { *offset }; - // read from specified offset and write new offset back - let mut bytes_read = 0; - while bytes_read < count { - let len = min(buffer.len(), count - bytes_read); - let read_len = in_file.read_at(read_offset, &mut buffer[..len])?; - if read_len == 0 { - break; - } - bytes_read += read_len; - read_offset += read_len; - let mut bytes_written = 0; - while bytes_written < read_len { - let write_len = out_file.write(&buffer[bytes_written..])?; - if write_len == 0 { - return Err(SysError::EBADF); - } - bytes_written += write_len; + in_file.seek(SeekFrom::Current(0))? as usize + }; + + // read from specified offset and write new offset back + let mut bytes_read = 0; + while bytes_read < count { + let len = min(buffer.len(), count - bytes_read); + let read_len = in_file.read_at(read_offset, &mut buffer[..len])?; + if read_len == 0 { + break; + } + bytes_read += read_len; + read_offset += read_len; + let mut bytes_written = 0; + while bytes_written < read_len { + let write_len = out_file.write(&buffer[bytes_written..])?; + if write_len == 0 { + return Err(SysError::EBADF); } + bytes_written += write_len; } + } + + if !offset_ptr.is_null() { unsafe { - *offset = read_offset; + offset_ptr.write(read_offset); } - return Ok(bytes_read); + } else { + in_file.seek(SeekFrom::Current(bytes_read as i64))?; } + return Ok(bytes_read); } impl Process { diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index 046bd71..23487d7 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -229,6 +229,10 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize { Err(SysError::EACCES) } SYS_SETPRIORITY => sys_set_priority(args[0]), + SYS_PRCTL => { + warn!("ptctl is unimplemented"); + Ok(0) + } // SYS_SETRLIMIT => sys_setrlimit(), SYS_SYNC => sys_sync(), SYS_MOUNT => { @@ -264,6 +268,10 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize { SYS_MKDIRAT => sys_mkdirat(args[0], args[1] as *const u8, args[2]), // SYS_MKNODAT => sys_mknod(), // 260 + SYS_FCHMODAT => { + warn!("sys_fchmodat is unimplemented"); + Ok(0) + } SYS_FCHOWNAT => { warn!("sys_fchownat is unimplemented"); Ok(0)