Skip to content

Commit

Permalink
修复问题
Browse files Browse the repository at this point in the history
  • Loading branch information
fslongjin committed Jul 27, 2024
1 parent ff991d0 commit e6dfeea
Show file tree
Hide file tree
Showing 9 changed files with 123 additions and 69 deletions.
8 changes: 4 additions & 4 deletions kernel/src/arch/x86_64/process/syscall.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use alloc::{string::String, sync::Arc, vec::Vec};
use alloc::{ffi::CString, string::String, sync::Arc, vec::Vec};
use system_error::SystemError;

use crate::{
Expand All @@ -19,14 +19,14 @@ use crate::{
impl Syscall {
pub fn do_execve(
path: String,
argv: Vec<String>,
envp: Vec<String>,
argv: Vec<CString>,
envp: Vec<CString>,
regs: &mut TrapFrame,
) -> Result<(), SystemError> {
// 关中断,防止在设置地址空间的时候,发生中断,然后进调度器,出现错误。
let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
let pcb = ProcessManager::current_pcb();
// crate::debug!(
// log::debug!(
// "pid: {:?} do_execve: path: {:?}, argv: {:?}, envp: {:?}\n",
// pcb.pid(),
// path,
Expand Down
6 changes: 4 additions & 2 deletions kernel/src/filesystem/vfs/open.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,9 @@ pub(super) fn do_faccessat(
// let follow_symlink = flags & AtFlags::AT_SYMLINK_NOFOLLOW.bits() as u32 == 0;

let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?;
let path = path.to_str().map_err(|_| SystemError::EINVAL)?;

let (inode, path) = user_path_at(&ProcessManager::current_pcb(), dirfd, &path)?;
let (inode, path) = user_path_at(&ProcessManager::current_pcb(), dirfd, path)?;

// 如果找不到文件,则返回错误码ENOENT
let _inode = inode.lookup_follow_symlink(path.as_str(), VFS_MAX_FOLLOW_SYMLINK_TIMES)?;
Expand All @@ -50,8 +51,9 @@ pub(super) fn do_faccessat(

pub fn do_fchmodat(dirfd: i32, path: *const u8, _mode: ModeType) -> Result<usize, SystemError> {
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?;
let path = path.to_str().map_err(|_| SystemError::EINVAL)?;

let (inode, path) = user_path_at(&ProcessManager::current_pcb(), dirfd, &path)?;
let (inode, path) = user_path_at(&ProcessManager::current_pcb(), dirfd, path)?;

// 如果找不到文件,则返回错误码ENOENT
let _inode = inode.lookup_follow_symlink(path.as_str(), VFS_MAX_FOLLOW_SYMLINK_TIMES)?;
Expand Down
92 changes: 69 additions & 23 deletions kernel/src/filesystem/vfs/syscall.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use core::ffi::c_void;
use core::mem::size_of;

use alloc::string::ToString;
use alloc::{string::String, sync::Arc, vec::Vec};
use log::warn;
use system_error::SystemError;
Expand Down Expand Up @@ -484,7 +483,10 @@ impl Syscall {
mode: u32,
follow_symlink: bool,
) -> Result<usize, SystemError> {
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?;
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?
.into_string()
.map_err(|_| SystemError::EINVAL)?;

let open_flags: FileMode = FileMode::from_bits(o_flags).ok_or(SystemError::EINVAL)?;
let mode = ModeType::from_bits(mode).ok_or(SystemError::EINVAL)?;
return do_sys_open(
Expand All @@ -503,7 +505,10 @@ impl Syscall {
mode: u32,
follow_symlink: bool,
) -> Result<usize, SystemError> {
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?;
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?
.into_string()
.map_err(|_| SystemError::EINVAL)?;

let open_flags: FileMode = FileMode::from_bits(o_flags).ok_or(SystemError::EINVAL)?;
let mode = ModeType::from_bits(mode).ok_or(SystemError::EINVAL)?;
return do_sys_open(dirfd, &path, open_flags, mode, follow_symlink);
Expand Down Expand Up @@ -682,7 +687,10 @@ impl Syscall {
return Err(SystemError::EFAULT);
}

let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?;
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?
.into_string()
.map_err(|_| SystemError::EINVAL)?;

let proc = ProcessManager::current_pcb();
// Copy path to kernel space to avoid some security issues
let mut new_path = String::from("");
Expand Down Expand Up @@ -786,7 +794,10 @@ impl Syscall {
///
/// @return uint64_t 负数错误码 / 0表示成功
pub fn mkdir(path: *const u8, mode: usize) -> Result<usize, SystemError> {
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?;
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?
.into_string()
.map_err(|_| SystemError::EINVAL)?;

do_mkdir_at(
AtFlags::AT_FDCWD.bits(),
&path,
Expand Down Expand Up @@ -861,7 +872,10 @@ impl Syscall {

pub fn link(old: *const u8, new: *const u8) -> Result<usize, SystemError> {
let get_path = |cstr: *const u8| -> Result<String, SystemError> {
let res = check_and_clone_cstr(cstr, Some(MAX_PATHLEN))?;
let res = check_and_clone_cstr(cstr, Some(MAX_PATHLEN))?
.into_string()
.map_err(|_| SystemError::EINVAL)?;

if res.len() >= MAX_PATHLEN {
return Err(SystemError::ENAMETOOLONG);
}
Expand All @@ -888,8 +902,12 @@ impl Syscall {
new: *const u8,
flags: i32,
) -> Result<usize, SystemError> {
let old = check_and_clone_cstr(old, Some(MAX_PATHLEN))?;
let new = check_and_clone_cstr(new, Some(MAX_PATHLEN))?;
let old = check_and_clone_cstr(old, Some(MAX_PATHLEN))?
.into_string()
.map_err(|_| SystemError::EINVAL)?;
let new = check_and_clone_cstr(new, Some(MAX_PATHLEN))?
.into_string()
.map_err(|_| SystemError::EINVAL)?;
if old.len() >= MAX_PATHLEN || new.len() >= MAX_PATHLEN {
return Err(SystemError::ENAMETOOLONG);
}
Expand All @@ -913,7 +931,9 @@ impl Syscall {
pub fn unlinkat(dirfd: i32, path: *const u8, flags: u32) -> Result<usize, SystemError> {
let flags = AtFlags::from_bits(flags as i32).ok_or(SystemError::EINVAL)?;

let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?;
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?
.into_string()
.map_err(|_| SystemError::EINVAL)?;

if flags.contains(AtFlags::AT_REMOVEDIR) {
// debug!("rmdir");
Expand All @@ -938,12 +958,16 @@ impl Syscall {
}

pub fn rmdir(path: *const u8) -> Result<usize, SystemError> {
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?;
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?
.into_string()
.map_err(|_| SystemError::EINVAL)?;
return do_remove_dir(AtFlags::AT_FDCWD.bits(), &path).map(|v| v as usize);
}

pub fn unlink(path: *const u8) -> Result<usize, SystemError> {
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?;
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?
.into_string()
.map_err(|_| SystemError::EINVAL)?;
return do_unlink_at(AtFlags::AT_FDCWD.bits(), &path).map(|v| v as usize);
}

Expand All @@ -970,8 +994,14 @@ impl Syscall {
filename_to: *const u8,
_flags: u32,
) -> Result<usize, SystemError> {
let filename_from = check_and_clone_cstr(filename_from, Some(MAX_PATHLEN)).unwrap();
let filename_to = check_and_clone_cstr(filename_to, Some(MAX_PATHLEN)).unwrap();
let filename_from = check_and_clone_cstr(filename_from, Some(MAX_PATHLEN))
.unwrap()
.into_string()
.map_err(|_| SystemError::EINVAL)?;
let filename_to = check_and_clone_cstr(filename_to, Some(MAX_PATHLEN))
.unwrap()
.into_string()
.map_err(|_| SystemError::EINVAL)?;
// 文件名过长
if filename_from.len() > MAX_PATHLEN || filename_to.len() > MAX_PATHLEN {
return Err(SystemError::ENAMETOOLONG);
Expand Down Expand Up @@ -1315,7 +1345,10 @@ impl Syscall {
ModeType::empty().bits(),
true,
)?;
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN)).unwrap();
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))
.unwrap()
.into_string()
.map_err(|_| SystemError::EINVAL)?;
let pcb = ProcessManager::current_pcb();
let (_inode_begin, remain_path) = user_path_at(&pcb, fd as i32, &path)?;
let inode = ROOT_INODE().lookup_follow_symlink(&remain_path, MAX_PATHLEN)?;
Expand Down Expand Up @@ -1450,7 +1483,9 @@ impl Syscall {
mode: ModeType,
dev_t: DeviceNumber,
) -> Result<usize, SystemError> {
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?;
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?
.into_string()
.map_err(|_| SystemError::EINVAL)?;
let path = path.as_str().trim();

let inode: Result<Arc<dyn IndexNode>, SystemError> =
Expand Down Expand Up @@ -1499,7 +1534,9 @@ impl Syscall {
user_buf: *mut u8,
buf_size: usize,
) -> Result<usize, SystemError> {
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?;
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?
.into_string()
.map_err(|_| SystemError::EINVAL)?;
let path = path.as_str().trim();
let mut user_buf = UserBufferWriter::new(user_buf, buf_size, true)?;

Expand Down Expand Up @@ -1601,13 +1638,16 @@ impl Syscall {
_mountflags: usize,
_data: *const c_void,
) -> Result<usize, SystemError> {
let target = user_access::check_and_clone_cstr(target, Some(MAX_PATHLEN))?;
let target = user_access::check_and_clone_cstr(target, Some(MAX_PATHLEN))?
.into_string()
.map_err(|_| SystemError::EINVAL)?;

let filesystemtype = user_access::check_and_clone_cstr(filesystemtype, Some(MAX_PATHLEN))?;
let fstype_str = user_access::check_and_clone_cstr(filesystemtype, Some(MAX_PATHLEN))?;
let fstype_str = fstype_str.to_str().map_err(|_| SystemError::EINVAL)?;

let filesystemtype = producefs!(FSMAKER, filesystemtype)?;
let fstype = producefs!(FSMAKER, fstype_str)?;

Vcore::do_mount(filesystemtype, target.to_string().as_str())?;
Vcore::do_mount(fstype, &target)?;

return Ok(0);
}
Expand All @@ -1621,7 +1661,9 @@ impl Syscall {
///
/// [umount(2) — Linux manual page](https://www.man7.org/linux/man-pages/man2/umount.2.html)
pub fn umount2(target: *const u8, flags: i32) -> Result<(), SystemError> {
let target = user_access::check_and_clone_cstr(target, Some(MAX_PATHLEN))?;
let target = user_access::check_and_clone_cstr(target, Some(MAX_PATHLEN))?
.into_string()
.map_err(|_| SystemError::EINVAL)?;
Vcore::do_umount2(
AtFlags::AT_FDCWD.bits(),
&target,
Expand All @@ -1639,7 +1681,9 @@ impl Syscall {
let pathname = if pathname.is_null() {
None
} else {
let pathname = check_and_clone_cstr(pathname, Some(MAX_PATHLEN))?;
let pathname = check_and_clone_cstr(pathname, Some(MAX_PATHLEN))?
.into_string()
.map_err(|_| SystemError::EINVAL)?;
Some(pathname)
};
let flags = UtimensFlags::from_bits(flags).ok_or(SystemError::EINVAL)?;
Expand All @@ -1657,7 +1701,9 @@ impl Syscall {
pathname: *const u8,
times: *const PosixTimeval,
) -> Result<usize, SystemError> {
let pathname = check_and_clone_cstr(pathname, Some(MAX_PATHLEN))?;
let pathname = check_and_clone_cstr(pathname, Some(MAX_PATHLEN))?
.into_string()
.map_err(|_| SystemError::EINVAL)?;
let times = if times.is_null() {
None
} else {
Expand Down
12 changes: 6 additions & 6 deletions kernel/src/init/initial_kthread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use core::sync::atomic::{compiler_fence, Ordering};

use alloc::string::{String, ToString};
use alloc::{ffi::CString, string::ToString};
use log::{debug, error};
use system_error::SystemError;

Expand Down Expand Up @@ -86,7 +86,7 @@ fn switch_to_user() -> ! {
}

fn try_to_run_init_process(path: &str, trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
if let Err(e) = run_init_process(path.to_string(), trap_frame) {
if let Err(e) = run_init_process(path, trap_frame) {
if e != SystemError::ENOENT {
error!(
"Failed to run init process: {path} exists but couldn't execute it (error {:?})",
Expand All @@ -98,11 +98,11 @@ fn try_to_run_init_process(path: &str, trap_frame: &mut TrapFrame) -> Result<(),
Ok(())
}

fn run_init_process(path: String, trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
let argv = vec![path.clone()];
let envp = vec![String::from("PATH=/")];
fn run_init_process(path: &str, trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
let argv = vec![CString::new(path).unwrap()];
let envp = vec![CString::new("PATH=/").unwrap()];

compiler_fence(Ordering::SeqCst);
Syscall::do_execve(path, argv, envp, trap_frame)?;
Syscall::do_execve(path.to_string(), argv, envp, trap_frame)?;
Ok(())
}
27 changes: 14 additions & 13 deletions kernel/src/process/exec.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use core::{fmt::Debug, ptr::null};

use alloc::{collections::BTreeMap, string::String, sync::Arc, vec::Vec};
use alloc::{collections::BTreeMap, ffi::CString, string::String, sync::Arc, vec::Vec};
use system_error::SystemError;

use crate::{
Expand All @@ -16,6 +16,8 @@ use crate::{
},
};

use super::ProcessManager;

/// 系统支持的所有二进制文件加载器的列表
const BINARY_LOADERS: [&'static dyn BinaryLoader; 1] = [&ELF_LOADER];

Expand Down Expand Up @@ -125,7 +127,7 @@ impl ExecParam {
file,
vm,
flags,
init_info: ProcInitInfo::new(),
init_info: ProcInitInfo::new(ProcessManager::current_pcb().basic().name()),
})
}

Expand Down Expand Up @@ -195,16 +197,16 @@ pub fn load_binary_file(param: &mut ExecParam) -> Result<BinaryLoaderResult, Sys
/// 程序初始化信息,这些信息会被压入用户栈中
#[derive(Debug)]
pub struct ProcInitInfo {
pub proc_name: String,
pub args: Vec<String>,
pub envs: Vec<String>,
pub proc_name: CString,
pub args: Vec<CString>,
pub envs: Vec<CString>,
pub auxv: BTreeMap<u8, usize>,
}

impl ProcInitInfo {
pub fn new() -> Self {
pub fn new(proc_name: &str) -> Self {
Self {
proc_name: String::new(),
proc_name: CString::new(proc_name).unwrap_or(CString::new("").unwrap()),
args: Vec::new(),
envs: Vec::new(),
auxv: BTreeMap::new(),
Expand All @@ -229,17 +231,16 @@ impl ProcInitInfo {
.envs
.iter()
.map(|s| {
self.push_str(ustack, s.as_str()).expect("push_str failed");
self.push_str(ustack, s).expect("push_str failed");
ustack.sp()
})
.collect::<Vec<_>>();

// 然后把参数压入栈中
let argps = self
.args
.iter()
.map(|s| {
self.push_str(ustack, s.as_str()).expect("push_str failed");
self.push_str(ustack, s).expect("push_str failed");
ustack.sp()
})
.collect::<Vec<_>>();
Expand Down Expand Up @@ -280,9 +281,9 @@ impl ProcInitInfo {
return Ok(());
}

fn push_str(&self, ustack: &mut UserStack, s: &str) -> Result<(), SystemError> {
self.push_slice(ustack, &[b"\0"])?;
self.push_slice(ustack, s.as_bytes())?;
fn push_str(&self, ustack: &mut UserStack, s: &CString) -> Result<(), SystemError> {
let bytes = s.as_bytes_with_nul();
self.push_slice(ustack, bytes)?;
return Ok(());
}
}
Loading

0 comments on commit e6dfeea

Please sign in to comment.