fix: 修复由于升级到2024-07-23工具链之后,某些机器上面内核运行一直fault的问题。 (#870)

* fix: 修复由于升级到2024-07-23工具链之后,某些机器上面内核运行一直fault的问题。
This commit is contained in:
LoGin 2024-07-27 17:34:05 +08:00 committed by GitHub
parent 3c0a1c8fa2
commit 703ce5a77c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 138 additions and 82 deletions

View File

@ -156,14 +156,14 @@ log-monitor:
.PHONY: update-submodules .PHONY: update-submodules
update-submodules: update-submodules:
@echo "更新子模块" @echo "更新子模块"
@git submodule update --recursive @git submodule update --recursive --init
@git submodule foreach git pull origin master @git submodule foreach git pull origin master
.PHONY: update-submodules-by-mirror .PHONY: update-submodules-by-mirror
update-submodules-by-mirror: update-submodules-by-mirror:
@echo "从镜像更新子模块" @echo "从镜像更新子模块"
@git config --global url."https://git.mirrors.dragonos.org.cn/DragonOS-Community/".insteadOf https://github.com/DragonOS-Community/ @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 @git config --global --unset url."https://git.mirrors.dragonos.org.cn/DragonOS-Community/".insteadOf
help: help:

View File

@ -6,8 +6,7 @@
runner = "bootimage runner" runner = "bootimage runner"
[build] [build]
# '-Zlinker-features=-lld' 禁用rustlld20240723因为它与linkme0.3版本冲突 rustflags = ["-Clink-args=-znostart-stop-gc"]
rustflags = ["-Zlinker-features=-lld"] rustdocflags = ["-Clink-args=-znostart-stop-gc"]
rustdocflags = ["-Zlinker-features=-lld"]
[env] [env]

View File

@ -25,9 +25,9 @@ clean:
.PHONY: fmt .PHONY: fmt
fmt: fmt:
@cargo fmt --all $(FMT_CHECK) RUSTFLAGS="$(RUSTFLAGS)" cargo fmt --all $(FMT_CHECK)
ifeq ($(ARCH), x86_64) ifeq ($(ARCH), x86_64)
@cargo clippy --all-features RUSTFLAGS="$(RUSTFLAGS)" cargo clippy --all-features
endif endif
@ -36,12 +36,12 @@ check: ECHO
# @echo "Checking kernel... ARCH=$(ARCH)" # @echo "Checking kernel... ARCH=$(ARCH)"
# @exit 1 # @exit 1
ifeq ($(ARCH), x86_64) 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) 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 endif
test: test:
# 测试内核库 # 测试内核库
@cargo +nightly-2024-07-23 test --workspace --exclude dragonos_kernel RUSTFLAGS="$(RUSTFLAGS)" cargo +nightly-2024-07-23 test --workspace --exclude dragonos_kernel

View File

@ -42,3 +42,6 @@ endif
ifeq ($(DEBUG), DEBUG) ifeq ($(DEBUG), DEBUG)
GLOBAL_CFLAGS += -g GLOBAL_CFLAGS += -g
endif endif
export RUSTFLAGS := -C link-args=-znostart-stop-gc
export RUSTDOCFLAGS := -C link-args=-znostart-stop-gc

View File

@ -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 riscv::register::sstatus::{FS, SPP};
use system_error::SystemError; use system_error::SystemError;
@ -16,8 +16,8 @@ use crate::{
impl Syscall { impl Syscall {
pub fn do_execve( pub fn do_execve(
path: String, path: String,
argv: Vec<String>, argv: Vec<CString>,
envp: Vec<String>, envp: Vec<CString>,
regs: &mut TrapFrame, regs: &mut TrapFrame,
) -> Result<(), SystemError> { ) -> Result<(), SystemError> {
// 关中断,防止在设置地址空间的时候,发生中断,然后进调度器,出现错误。 // 关中断,防止在设置地址空间的时候,发生中断,然后进调度器,出现错误。

View File

@ -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 system_error::SystemError;
use crate::{ use crate::{
@ -19,14 +19,14 @@ use crate::{
impl Syscall { impl Syscall {
pub fn do_execve( pub fn do_execve(
path: String, path: String,
argv: Vec<String>, argv: Vec<CString>,
envp: Vec<String>, envp: Vec<CString>,
regs: &mut TrapFrame, regs: &mut TrapFrame,
) -> Result<(), SystemError> { ) -> Result<(), SystemError> {
// 关中断,防止在设置地址空间的时候,发生中断,然后进调度器,出现错误。 // 关中断,防止在设置地址空间的时候,发生中断,然后进调度器,出现错误。
let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
let pcb = ProcessManager::current_pcb(); let pcb = ProcessManager::current_pcb();
// crate::debug!( // log::debug!(
// "pid: {:?} do_execve: path: {:?}, argv: {:?}, envp: {:?}\n", // "pid: {:?} do_execve: path: {:?}, argv: {:?}, envp: {:?}\n",
// pcb.pid(), // pcb.pid(),
// path, // path,

View File

@ -38,8 +38,9 @@ pub(super) fn do_faccessat(
// let follow_symlink = flags & AtFlags::AT_SYMLINK_NOFOLLOW.bits() as u32 == 0; // let follow_symlink = flags & AtFlags::AT_SYMLINK_NOFOLLOW.bits() as u32 == 0;
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?; 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 // 如果找不到文件则返回错误码ENOENT
let _inode = inode.lookup_follow_symlink(path.as_str(), VFS_MAX_FOLLOW_SYMLINK_TIMES)?; 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<usize, SystemError> { 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 = 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 // 如果找不到文件则返回错误码ENOENT
let _inode = inode.lookup_follow_symlink(path.as_str(), VFS_MAX_FOLLOW_SYMLINK_TIMES)?; let _inode = inode.lookup_follow_symlink(path.as_str(), VFS_MAX_FOLLOW_SYMLINK_TIMES)?;

View File

@ -1,7 +1,6 @@
use core::ffi::c_void; use core::ffi::c_void;
use core::mem::size_of; use core::mem::size_of;
use alloc::string::ToString;
use alloc::{string::String, sync::Arc, vec::Vec}; use alloc::{string::String, sync::Arc, vec::Vec};
use log::warn; use log::warn;
use system_error::SystemError; use system_error::SystemError;
@ -484,7 +483,10 @@ impl Syscall {
mode: u32, mode: u32,
follow_symlink: bool, follow_symlink: bool,
) -> Result<usize, SystemError> { ) -> 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 open_flags: FileMode = FileMode::from_bits(o_flags).ok_or(SystemError::EINVAL)?;
let mode = ModeType::from_bits(mode).ok_or(SystemError::EINVAL)?; let mode = ModeType::from_bits(mode).ok_or(SystemError::EINVAL)?;
return do_sys_open( return do_sys_open(
@ -503,7 +505,10 @@ impl Syscall {
mode: u32, mode: u32,
follow_symlink: bool, follow_symlink: bool,
) -> Result<usize, SystemError> { ) -> 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 open_flags: FileMode = FileMode::from_bits(o_flags).ok_or(SystemError::EINVAL)?;
let mode = ModeType::from_bits(mode).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); return do_sys_open(dirfd, &path, open_flags, mode, follow_symlink);
@ -682,7 +687,10 @@ impl Syscall {
return Err(SystemError::EFAULT); 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(); let proc = ProcessManager::current_pcb();
// Copy path to kernel space to avoid some security issues // Copy path to kernel space to avoid some security issues
let mut new_path = String::from(""); let mut new_path = String::from("");
@ -786,7 +794,10 @@ impl Syscall {
/// ///
/// @return uint64_t 负数错误码 / 0表示成功 /// @return uint64_t 负数错误码 / 0表示成功
pub fn mkdir(path: *const u8, mode: usize) -> Result<usize, SystemError> { 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( do_mkdir_at(
AtFlags::AT_FDCWD.bits(), AtFlags::AT_FDCWD.bits(),
&path, &path,
@ -861,7 +872,10 @@ impl Syscall {
pub fn link(old: *const u8, new: *const u8) -> Result<usize, SystemError> { pub fn link(old: *const u8, new: *const u8) -> Result<usize, SystemError> {
let get_path = |cstr: *const u8| -> Result<String, 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 { if res.len() >= MAX_PATHLEN {
return Err(SystemError::ENAMETOOLONG); return Err(SystemError::ENAMETOOLONG);
} }
@ -888,8 +902,12 @@ impl Syscall {
new: *const u8, new: *const u8,
flags: i32, flags: i32,
) -> Result<usize, SystemError> { ) -> Result<usize, SystemError> {
let old = check_and_clone_cstr(old, Some(MAX_PATHLEN))?; let old = check_and_clone_cstr(old, Some(MAX_PATHLEN))?
let new = check_and_clone_cstr(new, 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 { if old.len() >= MAX_PATHLEN || new.len() >= MAX_PATHLEN {
return Err(SystemError::ENAMETOOLONG); return Err(SystemError::ENAMETOOLONG);
} }
@ -913,7 +931,9 @@ impl Syscall {
pub fn unlinkat(dirfd: i32, path: *const u8, flags: u32) -> Result<usize, SystemError> { 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 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) { if flags.contains(AtFlags::AT_REMOVEDIR) {
// debug!("rmdir"); // debug!("rmdir");
@ -938,12 +958,16 @@ impl Syscall {
} }
pub fn rmdir(path: *const u8) -> Result<usize, SystemError> { 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); return do_remove_dir(AtFlags::AT_FDCWD.bits(), &path).map(|v| v as usize);
} }
pub fn unlink(path: *const u8) -> Result<usize, SystemError> { 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); return do_unlink_at(AtFlags::AT_FDCWD.bits(), &path).map(|v| v as usize);
} }
@ -970,8 +994,14 @@ impl Syscall {
filename_to: *const u8, filename_to: *const u8,
_flags: u32, _flags: u32,
) -> Result<usize, SystemError> { ) -> Result<usize, SystemError> {
let filename_from = check_and_clone_cstr(filename_from, Some(MAX_PATHLEN)).unwrap(); let filename_from = check_and_clone_cstr(filename_from, Some(MAX_PATHLEN))
let filename_to = check_and_clone_cstr(filename_to, Some(MAX_PATHLEN)).unwrap(); .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 { if filename_from.len() > MAX_PATHLEN || filename_to.len() > MAX_PATHLEN {
return Err(SystemError::ENAMETOOLONG); return Err(SystemError::ENAMETOOLONG);
@ -1315,7 +1345,10 @@ impl Syscall {
ModeType::empty().bits(), ModeType::empty().bits(),
true, 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 pcb = ProcessManager::current_pcb();
let (_inode_begin, remain_path) = user_path_at(&pcb, fd as i32, &path)?; let (_inode_begin, remain_path) = user_path_at(&pcb, fd as i32, &path)?;
let inode = ROOT_INODE().lookup_follow_symlink(&remain_path, MAX_PATHLEN)?; let inode = ROOT_INODE().lookup_follow_symlink(&remain_path, MAX_PATHLEN)?;
@ -1450,7 +1483,9 @@ impl Syscall {
mode: ModeType, mode: ModeType,
dev_t: DeviceNumber, dev_t: DeviceNumber,
) -> Result<usize, SystemError> { ) -> 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 path = path.as_str().trim();
let inode: Result<Arc<dyn IndexNode>, SystemError> = let inode: Result<Arc<dyn IndexNode>, SystemError> =
@ -1499,7 +1534,9 @@ impl Syscall {
user_buf: *mut u8, user_buf: *mut u8,
buf_size: usize, buf_size: usize,
) -> Result<usize, SystemError> { ) -> 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 path = path.as_str().trim();
let mut user_buf = UserBufferWriter::new(user_buf, buf_size, true)?; let mut user_buf = UserBufferWriter::new(user_buf, buf_size, true)?;
@ -1601,13 +1638,16 @@ impl Syscall {
_mountflags: usize, _mountflags: usize,
_data: *const c_void, _data: *const c_void,
) -> Result<usize, SystemError> { ) -> 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); 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) /// [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> { 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( Vcore::do_umount2(
AtFlags::AT_FDCWD.bits(), AtFlags::AT_FDCWD.bits(),
&target, &target,
@ -1639,7 +1681,9 @@ impl Syscall {
let pathname = if pathname.is_null() { let pathname = if pathname.is_null() {
None None
} else { } 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) Some(pathname)
}; };
let flags = UtimensFlags::from_bits(flags).ok_or(SystemError::EINVAL)?; let flags = UtimensFlags::from_bits(flags).ok_or(SystemError::EINVAL)?;
@ -1657,7 +1701,9 @@ impl Syscall {
pathname: *const u8, pathname: *const u8,
times: *const PosixTimeval, times: *const PosixTimeval,
) -> Result<usize, SystemError> { ) -> 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() { let times = if times.is_null() {
None None
} else { } else {

View File

@ -2,7 +2,7 @@
use core::sync::atomic::{compiler_fence, Ordering}; use core::sync::atomic::{compiler_fence, Ordering};
use alloc::string::{String, ToString}; use alloc::{ffi::CString, string::ToString};
use log::{debug, error}; use log::{debug, error};
use system_error::SystemError; 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> { 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 { if e != SystemError::ENOENT {
error!( error!(
"Failed to run init process: {path} exists but couldn't execute it (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(()) Ok(())
} }
fn run_init_process(path: String, trap_frame: &mut TrapFrame) -> Result<(), SystemError> { fn run_init_process(path: &str, trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
let argv = vec![path.clone()]; let argv = vec![CString::new(path).unwrap()];
let envp = vec![String::from("PATH=/")]; let envp = vec![CString::new("PATH=/").unwrap()];
compiler_fence(Ordering::SeqCst); compiler_fence(Ordering::SeqCst);
Syscall::do_execve(path, argv, envp, trap_frame)?; Syscall::do_execve(path.to_string(), argv, envp, trap_frame)?;
Ok(()) Ok(())
} }

View File

@ -1,6 +1,6 @@
use core::{fmt::Debug, ptr::null}; 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 system_error::SystemError;
use crate::{ use crate::{
@ -16,6 +16,8 @@ use crate::{
}, },
}; };
use super::ProcessManager;
/// 系统支持的所有二进制文件加载器的列表 /// 系统支持的所有二进制文件加载器的列表
const BINARY_LOADERS: [&'static dyn BinaryLoader; 1] = [&ELF_LOADER]; const BINARY_LOADERS: [&'static dyn BinaryLoader; 1] = [&ELF_LOADER];
@ -125,7 +127,7 @@ impl ExecParam {
file, file,
vm, vm,
flags, 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<BinaryLoaderResult, Sys
/// 程序初始化信息,这些信息会被压入用户栈中 /// 程序初始化信息,这些信息会被压入用户栈中
#[derive(Debug)] #[derive(Debug)]
pub struct ProcInitInfo { pub struct ProcInitInfo {
pub proc_name: String, pub proc_name: CString,
pub args: Vec<String>, pub args: Vec<CString>,
pub envs: Vec<String>, pub envs: Vec<CString>,
pub auxv: BTreeMap<u8, usize>, pub auxv: BTreeMap<u8, usize>,
} }
impl ProcInitInfo { impl ProcInitInfo {
pub fn new() -> Self { pub fn new(proc_name: &str) -> Self {
Self { Self {
proc_name: String::new(), proc_name: CString::new(proc_name).unwrap_or(CString::new("").unwrap()),
args: Vec::new(), args: Vec::new(),
envs: Vec::new(), envs: Vec::new(),
auxv: BTreeMap::new(), auxv: BTreeMap::new(),
@ -229,17 +231,16 @@ impl ProcInitInfo {
.envs .envs
.iter() .iter()
.map(|s| { .map(|s| {
self.push_str(ustack, s.as_str()).expect("push_str failed"); self.push_str(ustack, s).expect("push_str failed");
ustack.sp() ustack.sp()
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
// 然后把参数压入栈中 // 然后把参数压入栈中
let argps = self let argps = self
.args .args
.iter() .iter()
.map(|s| { .map(|s| {
self.push_str(ustack, s.as_str()).expect("push_str failed"); self.push_str(ustack, s).expect("push_str failed");
ustack.sp() ustack.sp()
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
@ -280,9 +281,9 @@ impl ProcInitInfo {
return Ok(()); return Ok(());
} }
fn push_str(&self, ustack: &mut UserStack, s: &str) -> Result<(), SystemError> { fn push_str(&self, ustack: &mut UserStack, s: &CString) -> Result<(), SystemError> {
self.push_slice(ustack, &[b"\0"])?; let bytes = s.as_bytes_with_nul();
self.push_slice(ustack, s.as_bytes())?; self.push_slice(ustack, bytes)?;
return Ok(()); return Ok(());
} }
} }

View File

@ -8,6 +8,7 @@ use core::{
}; };
use alloc::{ use alloc::{
ffi::CString,
string::{String, ToString}, string::{String, ToString},
sync::{Arc, Weak}, sync::{Arc, Weak},
vec::Vec, vec::Vec,
@ -922,11 +923,11 @@ impl ProcessControlBlock {
} }
/// 生成进程的名字 /// 生成进程的名字
pub fn generate_name(program_path: &str, args: &Vec<String>) -> String { pub fn generate_name(program_path: &str, args: &Vec<CString>) -> String {
let mut name = program_path.to_string(); let mut name = program_path.to_string();
for arg in args { for arg in args {
name.push(' '); name.push(' ');
name.push_str(arg); name.push_str(arg.to_string_lossy().as_ref());
} }
return name; return name;
} }

View File

@ -1,10 +1,7 @@
use core::ffi::c_void; use core::ffi::c_void;
use alloc::{ use alloc::{ffi::CString, string::ToString, sync::Arc, vec::Vec};
string::{String, ToString}, use log::error;
sync::Arc,
vec::Vec,
};
use system_error::SystemError; use system_error::SystemError;
use super::{ use super::{
@ -114,16 +111,16 @@ impl Syscall {
} }
let x = || { let x = || {
let path: String = check_and_clone_cstr(path, Some(MAX_PATHLEN))?; let path: CString = check_and_clone_cstr(path, Some(MAX_PATHLEN))?;
let argv: Vec<String> = check_and_clone_cstr_array(argv)?; let argv: Vec<CString> = check_and_clone_cstr_array(argv)?;
let envp: Vec<String> = check_and_clone_cstr_array(envp)?; let envp: Vec<CString> = check_and_clone_cstr_array(envp)?;
Ok((path, argv, envp)) Ok((path, argv, envp))
}; };
let r: Result<(String, Vec<String>, Vec<String>), SystemError> = x(); let (path, argv, envp) = x().inspect_err(|e: &SystemError| {
if let Err(e) = r { error!("Failed to execve: {:?}", e);
panic!("Failed to execve: {:?}", e); })?;
}
let (path, argv, envp) = r.unwrap(); let path = path.into_string().map_err(|_| SystemError::EINVAL)?;
ProcessManager::current_pcb() ProcessManager::current_pcb()
.basic_mut() .basic_mut()
.set_name(ProcessControlBlock::generate_name(&path, &argv)); .set_name(ProcessControlBlock::generate_name(&path, &argv));

View File

@ -1150,7 +1150,9 @@ impl Syscall {
back_color: u32, back_color: u32,
) -> Result<usize, SystemError> { ) -> Result<usize, SystemError> {
// todo: 删除这个系统调用 // 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 fr = (front_color & 0x00ff0000) >> 16;
let fg = (front_color & 0x0000ff00) >> 8; let fg = (front_color & 0x0000ff00) >> 8;
let fb = front_color & 0x000000ff; let fb = front_color & 0x000000ff;

View File

@ -2,10 +2,11 @@
use core::{ use core::{
mem::size_of, mem::size_of,
num::NonZero,
slice::{from_raw_parts, from_raw_parts_mut}, 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}; use crate::mm::{verify_area, VirtAddr};
@ -70,10 +71,11 @@ pub unsafe fn copy_from_user(dst: &mut [u8], src: VirtAddr) -> Result<usize, Sys
/// ## 错误 /// ## 错误
/// ///
/// - `EFAULT`:用户态地址不合法 /// - `EFAULT`:用户态地址不合法
/// - `EINVAL`:字符串不是合法的 C 字符串
pub fn check_and_clone_cstr( pub fn check_and_clone_cstr(
user: *const u8, user: *const u8,
max_length: Option<usize>, max_length: Option<usize>,
) -> Result<String, SystemError> { ) -> Result<CString, SystemError> {
if user.is_null() { if user.is_null() {
return Err(SystemError::EFAULT); return Err(SystemError::EFAULT);
} }
@ -93,9 +95,12 @@ pub fn check_and_clone_cstr(
if c[0] == 0 { if c[0] == 0 {
break; 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 字符串数组 /// 检查并从用户态拷贝一个 C 字符串数组
@ -112,7 +117,7 @@ pub fn check_and_clone_cstr(
/// ## 错误 /// ## 错误
/// ///
/// - `EFAULT`:用户态地址不合法 /// - `EFAULT`:用户态地址不合法
pub fn check_and_clone_cstr_array(user: *const *const u8) -> Result<Vec<String>, SystemError> { pub fn check_and_clone_cstr_array(user: *const *const u8) -> Result<Vec<CString>, SystemError> {
if user.is_null() { if user.is_null() {
Ok(Vec::new()) Ok(Vec::new())
} else { } else {