asterinas/kernel/src/syscall/execve.rs

89 lines
2.2 KiB
Rust
Raw Normal View History

2024-01-03 03:22:36 +00:00
// SPDX-License-Identifier: MPL-2.0
2025-09-25 11:40:52 +00:00
use ostd::arch::cpu::context::UserContext;
2022-10-26 09:47:38 +00:00
use super::{constants::*, SyscallReturn};
use crate::{
fs::{
2025-10-16 15:57:17 +00:00
file_table::FileDesc,
fs_resolver::{FsPath, AT_FDCWD},
path::Path,
},
prelude::*,
2025-09-25 11:40:52 +00:00
process::{check_executable_file, do_execve},
};
2022-10-26 09:47:38 +00:00
pub fn sys_execve(
filename_ptr: Vaddr,
argv_ptr_ptr: Vaddr,
envp_ptr_ptr: Vaddr,
ctx: &Context,
user_context: &mut UserContext,
) -> Result<SyscallReturn> {
2023-06-13 02:13:00 +00:00
let elf_file = {
2025-10-16 15:57:17 +00:00
let flags = OpenFlags::empty();
lookup_executable_file(AT_FDCWD, filename_ptr, flags, ctx)?
2023-06-13 02:13:00 +00:00
};
do_execve(elf_file, argv_ptr_ptr, envp_ptr_ptr, ctx, user_context)?;
2023-06-13 02:13:00 +00:00
Ok(SyscallReturn::NoReturn)
}
2023-06-13 02:13:00 +00:00
pub fn sys_execveat(
2024-05-08 12:01:11 +00:00
dfd: FileDesc,
2023-06-13 02:13:00 +00:00
filename_ptr: Vaddr,
argv_ptr_ptr: Vaddr,
envp_ptr_ptr: Vaddr,
flags: u32,
ctx: &Context,
user_context: &mut UserContext,
2023-06-13 02:13:00 +00:00
) -> Result<SyscallReturn> {
let elf_file = {
2025-10-16 15:57:17 +00:00
let flags = OpenFlags::from_bits(flags)
.ok_or_else(|| Error::with_message(Errno::EINVAL, "invalid flags"))?;
lookup_executable_file(dfd, filename_ptr, flags, ctx)?
};
do_execve(elf_file, argv_ptr_ptr, envp_ptr_ptr, ctx, user_context)?;
2023-06-13 02:13:00 +00:00
Ok(SyscallReturn::NoReturn)
}
fn lookup_executable_file(
2024-05-08 12:01:11 +00:00
dfd: FileDesc,
2025-10-16 15:57:17 +00:00
filename_ptr: Vaddr,
2023-06-13 02:13:00 +00:00
flags: OpenFlags,
ctx: &Context,
) -> Result<Path> {
2025-10-16 15:57:17 +00:00
let filename = ctx
.user_space()
.read_cstring(filename_ptr, MAX_FILENAME_LEN)?;
let path = {
let filename = filename.to_string_lossy();
let fs_path = if flags.contains(OpenFlags::AT_EMPTY_PATH) && filename.is_empty() {
FsPath::from_fd(dfd)?
} else {
FsPath::from_fd_and_path(dfd, &filename)?
};
let fs_ref = ctx.thread_local.borrow_fs();
let fs_resolver = fs_ref.resolver().read();
2023-06-13 02:13:00 +00:00
if flags.contains(OpenFlags::AT_SYMLINK_NOFOLLOW) {
2024-12-26 13:35:56 +00:00
fs_resolver.lookup_no_follow(&fs_path)?
2023-06-13 02:13:00 +00:00
} else {
2024-12-26 13:35:56 +00:00
fs_resolver.lookup(&fs_path)?
2023-06-13 02:13:00 +00:00
}
2024-12-26 13:35:56 +00:00
};
check_executable_file(&path)?;
2024-12-26 13:35:56 +00:00
Ok(path)
2023-06-13 02:13:00 +00:00
}
bitflags::bitflags! {
struct OpenFlags: u32 {
const AT_EMPTY_PATH = 0x1000;
const AT_SYMLINK_NOFOLLOW = 0x100;
}
}