Return correct error type if executing a file that is not executable

This commit is contained in:
Jianfeng Jiang
2023-08-16 17:39:27 +08:00
committed by Tate, Hongliang Tian
parent 3f15bcaf5d
commit 8aef80f978
3 changed files with 34 additions and 24 deletions

View File

@ -45,6 +45,10 @@ impl InodeType {
pub fn is_reguler_file(&self) -> bool { pub fn is_reguler_file(&self) -> bool {
*self == InodeType::File *self == InodeType::File
} }
pub fn is_directory(&self) -> bool {
*self == InodeType::Dir
}
} }
impl From<DeviceType> for InodeType { impl From<DeviceType> for InodeType {

View File

@ -35,7 +35,7 @@ pub fn load_program_to_root_vmar(
}; };
if let Some(mut new_argv) = parse_shebang_line(&*file_header)? { if let Some(mut new_argv) = parse_shebang_line(&*file_header)? {
if recursion_limit == 0 { if recursion_limit == 0 {
return_errno_with_message!(Errno::EINVAL, "the recursieve limit is reached"); return_errno_with_message!(Errno::ELOOP, "the recursieve limit is reached");
} }
new_argv.extend_from_slice(&argv); new_argv.extend_from_slice(&argv);
let interpreter = { let interpreter = {
@ -43,6 +43,7 @@ pub fn load_program_to_root_vmar(
let fs_path = FsPath::new(AT_FDCWD, &filename)?; let fs_path = FsPath::new(AT_FDCWD, &filename)?;
fs_resolver.lookup(&fs_path)? fs_resolver.lookup(&fs_path)?
}; };
check_executable_file(&interpreter)?;
return load_program_to_root_vmar( return load_program_to_root_vmar(
root_vmar, root_vmar,
interpreter, interpreter,
@ -56,3 +57,19 @@ pub fn load_program_to_root_vmar(
load_elf_to_root_vmar(root_vmar, &*file_header, elf_file, fs_resolver, argv, envp)?; load_elf_to_root_vmar(root_vmar, &*file_header, elf_file, fs_resolver, argv, envp)?;
Ok((abs_path, elf_load_info)) Ok((abs_path, elf_load_info))
} }
pub fn check_executable_file(dentry: &Arc<Dentry>) -> Result<()> {
if dentry.inode_type().is_directory() {
return_errno_with_message!(Errno::EISDIR, "the file is a directory");
}
if !dentry.inode_type().is_reguler_file() {
return_errno_with_message!(Errno::EACCES, "the dentry is not a regular file");
}
if !dentry.inode_mode().is_executable() {
return_errno_with_message!(Errno::EACCES, "the dentry is not executable");
}
Ok(())
}

View File

@ -8,7 +8,7 @@ use crate::log_syscall_entry;
use crate::prelude::*; use crate::prelude::*;
use crate::process::posix_thread::name::ThreadName; use crate::process::posix_thread::name::ThreadName;
use crate::process::posix_thread::posix_thread_ext::PosixThreadExt; use crate::process::posix_thread::posix_thread_ext::PosixThreadExt;
use crate::process::program_loader::load_program_to_root_vmar; use crate::process::program_loader::{check_executable_file, load_program_to_root_vmar};
use crate::syscall::{SYS_EXECVE, SYS_EXECVEAT}; use crate::syscall::{SYS_EXECVE, SYS_EXECVEAT};
use crate::util::{read_cstring_from_user, read_val_from_user}; use crate::util::{read_cstring_from_user, read_val_from_user};
@ -19,13 +19,11 @@ pub fn sys_execve(
context: &mut UserContext, context: &mut UserContext,
) -> Result<SyscallReturn> { ) -> Result<SyscallReturn> {
log_syscall_entry!(SYS_EXECVE); log_syscall_entry!(SYS_EXECVE);
let executable_path = read_filename(filename_ptr)?;
let elf_file = { let elf_file = {
let current = current!(); let executable_path = read_filename(filename_ptr)?;
let fs_resolver = current.fs().read(); lookup_executable_file(AT_FDCWD, executable_path, OpenFlags::empty())?
let fs_path = FsPath::new(AT_FDCWD, &executable_path)?;
fs_resolver.lookup(&fs_path)?
}; };
do_execve(elf_file, argv_ptr_ptr, envp_ptr_ptr, context)?; do_execve(elf_file, argv_ptr_ptr, envp_ptr_ptr, context)?;
Ok(SyscallReturn::NoReturn) Ok(SyscallReturn::NoReturn)
} }
@ -39,10 +37,13 @@ pub fn sys_execveat(
context: &mut UserContext, context: &mut UserContext,
) -> Result<SyscallReturn> { ) -> Result<SyscallReturn> {
log_syscall_entry!(SYS_EXECVEAT); log_syscall_entry!(SYS_EXECVEAT);
let elf_file = {
let flags = OpenFlags::from_bits_truncate(flags); let flags = OpenFlags::from_bits_truncate(flags);
let filename = read_filename(filename_ptr)?; let filename = read_filename(filename_ptr)?;
let elf_file = lookup_executable_file(dfd, filename, flags)?; lookup_executable_file(dfd, filename, flags)?
check_file_type_and_permission(&elf_file)?; };
do_execve(elf_file, argv_ptr_ptr, envp_ptr_ptr, context)?; do_execve(elf_file, argv_ptr_ptr, envp_ptr_ptr, context)?;
Ok(SyscallReturn::NoReturn) Ok(SyscallReturn::NoReturn)
} }
@ -68,22 +69,10 @@ fn lookup_executable_file(
fs_resolver.lookup(&fs_path) fs_resolver.lookup(&fs_path)
} }
}?; }?;
check_file_type_and_permission(&dentry)?; check_executable_file(&dentry)?;
Ok(dentry) Ok(dentry)
} }
fn check_file_type_and_permission(dentry: &Arc<Dentry>) -> Result<()> {
if !dentry.inode_type().is_reguler_file() {
return_errno_with_message!(Errno::EACCES, "the dentry is not a regular file");
}
if !dentry.inode_mode().is_executable() {
return_errno_with_message!(Errno::EACCES, "the dentry is not executable");
}
Ok(())
}
fn do_execve( fn do_execve(
elf_file: Arc<Dentry>, elf_file: Arc<Dentry>,
argv_ptr_ptr: Vaddr, argv_ptr_ptr: Vaddr,