From 26c34cd092ba37283076a6d33cb5d9535a4ff042 Mon Sep 17 00:00:00 2001 From: longjin Date: Sat, 27 Jul 2024 01:26:05 +0800 Subject: [PATCH 1/4] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E7=94=B1=E4=BA=8E?= =?UTF-8?q?=E5=8D=87=E7=BA=A7=E5=88=B02024-07-23=E5=B7=A5=E5=85=B7?= =?UTF-8?q?=E9=93=BE=E4=B9=8B=E5=90=8E=EF=BC=8C=E6=9F=90=E4=BA=9B=E6=9C=BA?= =?UTF-8?q?=E5=99=A8=E4=B8=8A=E9=9D=A2=E5=86=85=E6=A0=B8=E8=BF=90=E8=A1=8C?= =?UTF-8?q?=E4=B8=80=E7=9B=B4fault=E7=9A=84=E9=97=AE=E9=A2=98=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/.cargo/config.toml | 5 ++--- kernel/env.mk | 3 +++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/kernel/.cargo/config.toml b/kernel/.cargo/config.toml index 5c216cc97..c12d67fb7 100644 --- a/kernel/.cargo/config.toml +++ b/kernel/.cargo/config.toml @@ -6,8 +6,7 @@ runner = "bootimage runner" [build] -# '-Zlinker-features=-lld' 禁用rustlld(20240723),因为它与linkme0.3版本冲突 -rustflags = ["-Zlinker-features=-lld"] -rustdocflags = ["-Zlinker-features=-lld"] +rustflags = ["-Clink-args=-znostart-stop-gc"] +rustdocflags = ["-Clink-args=-znostart-stop-gc"] [env] diff --git a/kernel/env.mk b/kernel/env.mk index 666dcc5f5..7f3f3f605 100644 --- a/kernel/env.mk +++ b/kernel/env.mk @@ -42,3 +42,6 @@ endif ifeq ($(DEBUG), DEBUG) GLOBAL_CFLAGS += -g endif + +export RUSTFLAGS := -C link-args=-znostart-stop-gc +export RUSTDOCFLAGS := -C link-args=-znostart-stop-gc \ No newline at end of file From 1e3fc5f5dac4bd6f0afdbb098abfcddcf6c95989 Mon Sep 17 00:00:00 2001 From: longjin Date: Sat, 27 Jul 2024 02:01:30 +0800 Subject: [PATCH 2/4] 1 --- kernel/Makefile | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/kernel/Makefile b/kernel/Makefile index c9e28ed23..eb85f56e6 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -25,9 +25,9 @@ clean: .PHONY: fmt fmt: - @cargo fmt --all $(FMT_CHECK) + RUSTFLAGS=$(RUSTFLAGS) @cargo fmt --all $(FMT_CHECK) ifeq ($(ARCH), x86_64) - @cargo clippy --all-features + RUSTFLAGS=$(RUSTFLAGS) @cargo clippy --all-features endif @@ -36,12 +36,12 @@ check: ECHO # @echo "Checking kernel... ARCH=$(ARCH)" # @exit 1 ifeq ($(ARCH), x86_64) - @cargo +nightly-2024-07-23 check --workspace $(CARGO_ZBUILD) --message-format=json --target ./src/$(TARGET_JSON) + RUSTFLAGS=$(RUSTFLAGS) @cargo +nightly-2024-07-23 check --workspace $(CARGO_ZBUILD) --message-format=json --target ./src/$(TARGET_JSON) else ifeq ($(ARCH), riscv64) - @cargo +nightly-2024-07-23 check --workspace $(CARGO_ZBUILD) --message-format=json --target $(TARGET_JSON) + RUSTFLAGS=$(RUSTFLAGS) @cargo +nightly-2024-07-23 check --workspace $(CARGO_ZBUILD) --message-format=json --target $(TARGET_JSON) endif test: # 测试内核库 - @cargo +nightly-2024-07-23 test --workspace --exclude dragonos_kernel + RUSTFLAGS=$(RUSTFLAGS) @cargo +nightly-2024-07-23 test --workspace --exclude dragonos_kernel From ff991d0c4973413fc0a34c013454833d3c261067 Mon Sep 17 00:00:00 2001 From: longjin Date: Sat, 27 Jul 2024 02:06:30 +0800 Subject: [PATCH 3/4] 1 --- kernel/Makefile | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/kernel/Makefile b/kernel/Makefile index eb85f56e6..be85d3e7b 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -25,9 +25,9 @@ clean: .PHONY: fmt fmt: - RUSTFLAGS=$(RUSTFLAGS) @cargo fmt --all $(FMT_CHECK) + RUSTFLAGS="$(RUSTFLAGS)" cargo fmt --all $(FMT_CHECK) ifeq ($(ARCH), x86_64) - RUSTFLAGS=$(RUSTFLAGS) @cargo clippy --all-features + RUSTFLAGS="$(RUSTFLAGS)" cargo clippy --all-features endif @@ -36,12 +36,12 @@ check: ECHO # @echo "Checking kernel... ARCH=$(ARCH)" # @exit 1 ifeq ($(ARCH), x86_64) - RUSTFLAGS=$(RUSTFLAGS) @cargo +nightly-2024-07-23 check --workspace $(CARGO_ZBUILD) --message-format=json --target ./src/$(TARGET_JSON) + RUSTFLAGS="$(RUSTFLAGS)" cargo +nightly-2024-07-23 check --workspace $(CARGO_ZBUILD) --message-format=json --target ./src/$(TARGET_JSON) else ifeq ($(ARCH), riscv64) - RUSTFLAGS=$(RUSTFLAGS) @cargo +nightly-2024-07-23 check --workspace $(CARGO_ZBUILD) --message-format=json --target $(TARGET_JSON) + RUSTFLAGS="$(RUSTFLAGS)" cargo +nightly-2024-07-23 check --workspace $(CARGO_ZBUILD) --message-format=json --target $(TARGET_JSON) endif test: # 测试内核库 - RUSTFLAGS=$(RUSTFLAGS) @cargo +nightly-2024-07-23 test --workspace --exclude dragonos_kernel + RUSTFLAGS="$(RUSTFLAGS)" cargo +nightly-2024-07-23 test --workspace --exclude dragonos_kernel From 3ea61c7a0071e4c0681a5a65bb7cebad43758c96 Mon Sep 17 00:00:00 2001 From: longjin Date: Sat, 27 Jul 2024 15:25:19 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 4 +- kernel/src/arch/riscv64/process/syscall.rs | 6 +- kernel/src/arch/x86_64/process/syscall.rs | 8 +- kernel/src/filesystem/vfs/open.rs | 6 +- kernel/src/filesystem/vfs/syscall.rs | 92 ++++++++++++++++------ kernel/src/init/initial_kthread.rs | 12 +-- kernel/src/process/exec.rs | 27 ++++--- kernel/src/process/mod.rs | 5 +- kernel/src/process/syscall.rs | 23 +++--- kernel/src/syscall/mod.rs | 4 +- kernel/src/syscall/user_access.rs | 15 ++-- 11 files changed, 128 insertions(+), 74 deletions(-) diff --git a/Makefile b/Makefile index 015f17e4b..333f7c1b6 100644 --- a/Makefile +++ b/Makefile @@ -156,14 +156,14 @@ log-monitor: .PHONY: update-submodules update-submodules: @echo "更新子模块" - @git submodule update --recursive + @git submodule update --recursive --init @git submodule foreach git pull origin master .PHONY: update-submodules-by-mirror update-submodules-by-mirror: @echo "从镜像更新子模块" @git config --global url."https://git.mirrors.dragonos.org.cn/DragonOS-Community/".insteadOf https://github.com/DragonOS-Community/ - @$(MAKE) update-submodules + @$(MAKE) update-submodules --init @git config --global --unset url."https://git.mirrors.dragonos.org.cn/DragonOS-Community/".insteadOf help: diff --git a/kernel/src/arch/riscv64/process/syscall.rs b/kernel/src/arch/riscv64/process/syscall.rs index 224906534..b60f347b4 100644 --- a/kernel/src/arch/riscv64/process/syscall.rs +++ b/kernel/src/arch/riscv64/process/syscall.rs @@ -1,4 +1,4 @@ -use alloc::{string::String, vec::Vec}; +use alloc::{ffi::CString, string::String, vec::Vec}; use riscv::register::sstatus::{FS, SPP}; use system_error::SystemError; @@ -16,8 +16,8 @@ use crate::{ impl Syscall { pub fn do_execve( path: String, - argv: Vec, - envp: Vec, + argv: Vec, + envp: Vec, regs: &mut TrapFrame, ) -> Result<(), SystemError> { // 关中断,防止在设置地址空间的时候,发生中断,然后进调度器,出现错误。 diff --git a/kernel/src/arch/x86_64/process/syscall.rs b/kernel/src/arch/x86_64/process/syscall.rs index a356a4531..d2652beb9 100644 --- a/kernel/src/arch/x86_64/process/syscall.rs +++ b/kernel/src/arch/x86_64/process/syscall.rs @@ -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::{ @@ -19,14 +19,14 @@ use crate::{ impl Syscall { pub fn do_execve( path: String, - argv: Vec, - envp: Vec, + argv: Vec, + envp: Vec, 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, diff --git a/kernel/src/filesystem/vfs/open.rs b/kernel/src/filesystem/vfs/open.rs index f94908155..14f31fa10 100644 --- a/kernel/src/filesystem/vfs/open.rs +++ b/kernel/src/filesystem/vfs/open.rs @@ -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)?; @@ -50,8 +51,9 @@ pub(super) fn do_faccessat( pub fn do_fchmodat(dirfd: i32, path: *const u8, _mode: ModeType) -> Result { 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)?; diff --git a/kernel/src/filesystem/vfs/syscall.rs b/kernel/src/filesystem/vfs/syscall.rs index 63d90d4bd..e30c48836 100644 --- a/kernel/src/filesystem/vfs/syscall.rs +++ b/kernel/src/filesystem/vfs/syscall.rs @@ -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; @@ -484,7 +483,10 @@ impl Syscall { mode: u32, follow_symlink: bool, ) -> Result { - 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( @@ -503,7 +505,10 @@ impl Syscall { mode: u32, follow_symlink: bool, ) -> Result { - 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); @@ -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(""); @@ -786,7 +794,10 @@ impl Syscall { /// /// @return uint64_t 负数错误码 / 0表示成功 pub fn mkdir(path: *const u8, mode: usize) -> Result { - 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, @@ -861,7 +872,10 @@ impl Syscall { pub fn link(old: *const u8, new: *const u8) -> Result { let get_path = |cstr: *const u8| -> Result { - 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); } @@ -888,8 +902,12 @@ impl Syscall { new: *const u8, flags: i32, ) -> Result { - 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); } @@ -913,7 +931,9 @@ impl Syscall { pub fn unlinkat(dirfd: i32, path: *const u8, flags: u32) -> Result { 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"); @@ -938,12 +958,16 @@ impl Syscall { } pub fn rmdir(path: *const u8) -> Result { - 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 { - 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); } @@ -970,8 +994,14 @@ impl Syscall { filename_to: *const u8, _flags: u32, ) -> Result { - 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); @@ -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)?; @@ -1450,7 +1483,9 @@ impl Syscall { mode: ModeType, dev_t: DeviceNumber, ) -> Result { - 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, SystemError> = @@ -1499,7 +1534,9 @@ impl Syscall { user_buf: *mut u8, buf_size: usize, ) -> Result { - 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)?; @@ -1601,13 +1638,16 @@ impl Syscall { _mountflags: usize, _data: *const c_void, ) -> Result { - 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); } @@ -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, @@ -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)?; @@ -1657,7 +1701,9 @@ impl Syscall { pathname: *const u8, times: *const PosixTimeval, ) -> Result { - 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 { diff --git a/kernel/src/init/initial_kthread.rs b/kernel/src/init/initial_kthread.rs index 839024fca..0f7056a4c 100644 --- a/kernel/src/init/initial_kthread.rs +++ b/kernel/src/init/initial_kthread.rs @@ -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; @@ -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 {:?})", @@ -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(()) } diff --git a/kernel/src/process/exec.rs b/kernel/src/process/exec.rs index 94e219291..12af4c339 100644 --- a/kernel/src/process/exec.rs +++ b/kernel/src/process/exec.rs @@ -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::{ @@ -16,6 +16,8 @@ use crate::{ }, }; +use super::ProcessManager; + /// 系统支持的所有二进制文件加载器的列表 const BINARY_LOADERS: [&'static dyn BinaryLoader; 1] = [&ELF_LOADER]; @@ -125,7 +127,7 @@ impl ExecParam { file, vm, flags, - init_info: ProcInitInfo::new(), + init_info: ProcInitInfo::new(ProcessManager::current_pcb().basic().name()), }) } @@ -195,16 +197,16 @@ pub fn load_binary_file(param: &mut ExecParam) -> Result, - pub envs: Vec, + pub proc_name: CString, + pub args: Vec, + pub envs: Vec, pub auxv: BTreeMap, } 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(), @@ -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::>(); - // 然后把参数压入栈中 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::>(); @@ -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(()); } } diff --git a/kernel/src/process/mod.rs b/kernel/src/process/mod.rs index f4be134e8..f3d76ee88 100644 --- a/kernel/src/process/mod.rs +++ b/kernel/src/process/mod.rs @@ -8,6 +8,7 @@ use core::{ }; use alloc::{ + ffi::CString, string::{String, ToString}, sync::{Arc, Weak}, vec::Vec, @@ -922,11 +923,11 @@ impl ProcessControlBlock { } /// 生成进程的名字 - pub fn generate_name(program_path: &str, args: &Vec) -> String { + pub fn generate_name(program_path: &str, args: &Vec) -> String { let mut name = program_path.to_string(); for arg in args { name.push(' '); - name.push_str(arg); + name.push_str(arg.to_string_lossy().as_ref()); } return name; } diff --git a/kernel/src/process/syscall.rs b/kernel/src/process/syscall.rs index 16f0e2e45..86ffe5dd9 100644 --- a/kernel/src/process/syscall.rs +++ b/kernel/src/process/syscall.rs @@ -1,10 +1,7 @@ use core::ffi::c_void; -use alloc::{ - string::{String, ToString}, - sync::Arc, - vec::Vec, -}; +use alloc::{ffi::CString, string::ToString, sync::Arc, vec::Vec}; +use log::error; use system_error::SystemError; use super::{ @@ -114,16 +111,16 @@ impl Syscall { } let x = || { - let path: String = check_and_clone_cstr(path, Some(MAX_PATHLEN))?; - let argv: Vec = check_and_clone_cstr_array(argv)?; - let envp: Vec = check_and_clone_cstr_array(envp)?; + let path: CString = check_and_clone_cstr(path, Some(MAX_PATHLEN))?; + let argv: Vec = check_and_clone_cstr_array(argv)?; + let envp: Vec = check_and_clone_cstr_array(envp)?; Ok((path, argv, envp)) }; - let r: Result<(String, Vec, Vec), SystemError> = x(); - if let Err(e) = r { - panic!("Failed to execve: {:?}", e); - } - let (path, argv, envp) = r.unwrap(); + let (path, argv, envp) = x().inspect_err(|e: &SystemError| { + error!("Failed to execve: {:?}", e); + })?; + + let path = path.into_string().map_err(|_| SystemError::EINVAL)?; ProcessManager::current_pcb() .basic_mut() .set_name(ProcessControlBlock::generate_name(&path, &argv)); diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index cca260a03..c8cd45868 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -1150,7 +1150,9 @@ impl Syscall { back_color: u32, ) -> Result { // todo: 删除这个系统调用 - let s = check_and_clone_cstr(s, Some(4096))?; + let s = check_and_clone_cstr(s, Some(4096))? + .into_string() + .map_err(|_| SystemError::EINVAL)?; let fr = (front_color & 0x00ff0000) >> 16; let fg = (front_color & 0x0000ff00) >> 8; let fb = front_color & 0x000000ff; diff --git a/kernel/src/syscall/user_access.rs b/kernel/src/syscall/user_access.rs index c55f75674..18a74764e 100644 --- a/kernel/src/syscall/user_access.rs +++ b/kernel/src/syscall/user_access.rs @@ -2,10 +2,11 @@ use core::{ mem::size_of, + num::NonZero, slice::{from_raw_parts, from_raw_parts_mut}, }; -use alloc::{string::String, vec::Vec}; +use alloc::{ffi::CString, vec::Vec}; use crate::mm::{verify_area, VirtAddr}; @@ -70,10 +71,11 @@ pub unsafe fn copy_from_user(dst: &mut [u8], src: VirtAddr) -> Result, -) -> Result { +) -> Result { if user.is_null() { return Err(SystemError::EFAULT); } @@ -93,9 +95,12 @@ pub fn check_and_clone_cstr( if c[0] == 0 { break; } - buffer.push(c[0]); + buffer.push(NonZero::new(c[0]).ok_or(SystemError::EINVAL)?); } - String::from_utf8(buffer).map_err(|_| SystemError::EFAULT) + + let cstr = CString::from(buffer); + + return Ok(cstr); } /// 检查并从用户态拷贝一个 C 字符串数组 @@ -112,7 +117,7 @@ pub fn check_and_clone_cstr( /// ## 错误 /// /// - `EFAULT`:用户态地址不合法 -pub fn check_and_clone_cstr_array(user: *const *const u8) -> Result, SystemError> { +pub fn check_and_clone_cstr_array(user: *const *const u8) -> Result, SystemError> { if user.is_null() { Ok(Vec::new()) } else {