mirror of
https://github.com/hexagonal-sun/moss-kernel.git
synced 2025-12-23 22:47:55 -05:00
Merge pull request #72 from some100/master
This commit is contained in:
@@ -51,7 +51,7 @@
|
|||||||
| 0x30 (48) | faccessat | (int dfd, const char *filename, int mode) | __arm64_sys_faccessat | true |
|
| 0x30 (48) | faccessat | (int dfd, const char *filename, int mode) | __arm64_sys_faccessat | true |
|
||||||
| 0x31 (49) | chdir | (const char *filename) | __arm64_sys_chdir | true |
|
| 0x31 (49) | chdir | (const char *filename) | __arm64_sys_chdir | true |
|
||||||
| 0x32 (50) | fchdir | (unsigned int fd) | __arm64_sys_fchdir | false |
|
| 0x32 (50) | fchdir | (unsigned int fd) | __arm64_sys_fchdir | false |
|
||||||
| 0x33 (51) | chroot | (const char *filename) | __arm64_sys_chroot | false |
|
| 0x33 (51) | chroot | (const char *filename) | __arm64_sys_chroot | true |
|
||||||
| 0x34 (52) | fchmod | (unsigned int fd, umode_t mode) | __arm64_sys_fchmod | false |
|
| 0x34 (52) | fchmod | (unsigned int fd, umode_t mode) | __arm64_sys_fchmod | false |
|
||||||
| 0x35 (53) | fchmodat | (int dfd, const char *filename, umode_t mode) | __arm64_sys_fchmodat | false |
|
| 0x35 (53) | fchmodat | (int dfd, const char *filename, umode_t mode) | __arm64_sys_fchmodat | false |
|
||||||
| 0x36 (54) | fchownat | (int dfd, const char *filename, uid_t user, gid_t group, int flag) | __arm64_sys_fchownat | false |
|
| 0x36 (54) | fchownat | (int dfd, const char *filename, uid_t user, gid_t group, int flag) | __arm64_sys_fchownat | false |
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
use crate::fs::syscalls::chdir::sys_chroot;
|
||||||
use crate::fs::syscalls::trunc::sys_ftruncate;
|
use crate::fs::syscalls::trunc::sys_ftruncate;
|
||||||
use crate::kernel::power::sys_reboot;
|
use crate::kernel::power::sys_reboot;
|
||||||
use crate::kernel::rand::sys_getrandom;
|
use crate::kernel::rand::sys_getrandom;
|
||||||
@@ -100,6 +101,7 @@ pub async fn handle_syscall() {
|
|||||||
0x2e => sys_ftruncate(arg1.into(), arg2 as _).await,
|
0x2e => sys_ftruncate(arg1.into(), arg2 as _).await,
|
||||||
0x30 => sys_faccessat(arg1.into(), TUA::from_value(arg2 as _), arg3 as _).await,
|
0x30 => sys_faccessat(arg1.into(), TUA::from_value(arg2 as _), arg3 as _).await,
|
||||||
0x31 => sys_chdir(TUA::from_value(arg1 as _)).await,
|
0x31 => sys_chdir(TUA::from_value(arg1 as _)).await,
|
||||||
|
0x33 => sys_chroot(TUA::from_value(arg1 as _)).await,
|
||||||
0x38 => {
|
0x38 => {
|
||||||
sys_openat(
|
sys_openat(
|
||||||
arg1.into(),
|
arg1.into(),
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ use open_file::OpenFile;
|
|||||||
use reg::RegFile;
|
use reg::RegFile;
|
||||||
|
|
||||||
use crate::drivers::{DM, Driver};
|
use crate::drivers::{DM, Driver};
|
||||||
|
use crate::process::Task;
|
||||||
use crate::sync::SpinLock;
|
use crate::sync::SpinLock;
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
|
|
||||||
@@ -169,7 +170,52 @@ impl VFS {
|
|||||||
|
|
||||||
/// Resolves a path string to an Inode, starting from a given root for
|
/// Resolves a path string to an Inode, starting from a given root for
|
||||||
/// relative paths.
|
/// relative paths.
|
||||||
pub async fn resolve_path(&self, path: &Path, root: Arc<dyn Inode>) -> Result<Arc<dyn Inode>> {
|
pub async fn resolve_path(
|
||||||
|
&self,
|
||||||
|
path: &Path,
|
||||||
|
root: Arc<dyn Inode>,
|
||||||
|
task: Arc<Task>,
|
||||||
|
) -> Result<Arc<dyn Inode>> {
|
||||||
|
let mut current_inode = if path.is_absolute() {
|
||||||
|
task.root.lock_save_irq().0.clone() // use the task's root inode, in case a custom chroot was set
|
||||||
|
} else {
|
||||||
|
root
|
||||||
|
};
|
||||||
|
|
||||||
|
for component in path.components() {
|
||||||
|
// Before looking up the component, check if the current inode is a
|
||||||
|
// mount point. If so, traverse into the mounted filesystem's root.
|
||||||
|
if let Some(mount_root) = self
|
||||||
|
.state
|
||||||
|
.lock_save_irq()
|
||||||
|
.get_mount_root(¤t_inode.id())
|
||||||
|
{
|
||||||
|
current_inode = mount_root;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delegate the lookup to the underlying filesystem.
|
||||||
|
current_inode = current_inode.lookup(component).await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
// After the final lookup, check if the destination is itself a mount point.
|
||||||
|
if let Some(mount_root) = self
|
||||||
|
.state
|
||||||
|
.lock_save_irq()
|
||||||
|
.get_mount_root(¤t_inode.id())
|
||||||
|
{
|
||||||
|
current_inode = mount_root;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(current_inode)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Resolves a path string to an Inode, starting from a given root for
|
||||||
|
/// relative paths, and using the filesystem root inode for absolute paths.
|
||||||
|
pub async fn resolve_path_absolute(
|
||||||
|
&self,
|
||||||
|
path: &Path,
|
||||||
|
root: Arc<dyn Inode>,
|
||||||
|
) -> Result<Arc<dyn Inode>> {
|
||||||
let mut current_inode = if path.is_absolute() {
|
let mut current_inode = if path.is_absolute() {
|
||||||
self.root_inode
|
self.root_inode
|
||||||
.lock_save_irq()
|
.lock_save_irq()
|
||||||
@@ -218,9 +264,10 @@ impl VFS {
|
|||||||
flags: OpenFlags,
|
flags: OpenFlags,
|
||||||
root: Arc<dyn Inode>,
|
root: Arc<dyn Inode>,
|
||||||
mode: FilePermissions,
|
mode: FilePermissions,
|
||||||
|
task: Arc<Task>,
|
||||||
) -> Result<Arc<OpenFile>> {
|
) -> Result<Arc<OpenFile>> {
|
||||||
// Attempt to resolve the full path first.
|
// Attempt to resolve the full path first.
|
||||||
let resolve_result = self.resolve_path(path, root.clone()).await;
|
let resolve_result = self.resolve_path(path, root.clone(), task.clone()).await;
|
||||||
|
|
||||||
let target_inode = match resolve_result {
|
let target_inode = match resolve_result {
|
||||||
// The file/directory exists.
|
// The file/directory exists.
|
||||||
@@ -243,7 +290,7 @@ impl VFS {
|
|||||||
// (cwd or dirfd) as the parent directory.
|
// (cwd or dirfd) as the parent directory.
|
||||||
let file_name = path.file_name().ok_or(FsError::InvalidInput)?;
|
let file_name = path.file_name().ok_or(FsError::InvalidInput)?;
|
||||||
let parent_inode = if let Some(parent_path) = path.parent() {
|
let parent_inode = if let Some(parent_path) = path.parent() {
|
||||||
self.resolve_path(parent_path, root.clone()).await?
|
self.resolve_path(parent_path, root.clone(), task).await?
|
||||||
} else {
|
} else {
|
||||||
root.clone()
|
root.clone()
|
||||||
};
|
};
|
||||||
@@ -324,9 +371,10 @@ impl VFS {
|
|||||||
path: &Path,
|
path: &Path,
|
||||||
root: Arc<dyn Inode>,
|
root: Arc<dyn Inode>,
|
||||||
mode: FilePermissions,
|
mode: FilePermissions,
|
||||||
|
task: Arc<Task>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
// Try to resolve the target directory first.
|
// Try to resolve the target directory first.
|
||||||
match self.resolve_path(path, root.clone()).await {
|
match self.resolve_path(path, root.clone(), task.clone()).await {
|
||||||
// The path already exists, this is an error.
|
// The path already exists, this is an error.
|
||||||
Ok(_) => Err(FsError::AlreadyExists.into()),
|
Ok(_) => Err(FsError::AlreadyExists.into()),
|
||||||
|
|
||||||
@@ -339,7 +387,7 @@ impl VFS {
|
|||||||
// component (e.g., \"foo\"), treat the provided `root`
|
// component (e.g., \"foo\"), treat the provided `root`
|
||||||
// directory (AT_FDCWD / cwd / dirfd) as the parent.
|
// directory (AT_FDCWD / cwd / dirfd) as the parent.
|
||||||
let parent_inode = if let Some(parent_path) = path.parent() {
|
let parent_inode = if let Some(parent_path) = path.parent() {
|
||||||
self.resolve_path(parent_path, root.clone()).await?
|
self.resolve_path(parent_path, root.clone(), task).await?
|
||||||
} else {
|
} else {
|
||||||
root.clone()
|
root.clone()
|
||||||
};
|
};
|
||||||
@@ -362,9 +410,15 @@ impl VFS {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn unlink(&self, path: &Path, root: Arc<dyn Inode>, remove_dir: bool) -> Result<()> {
|
pub async fn unlink(
|
||||||
|
&self,
|
||||||
|
path: &Path,
|
||||||
|
root: Arc<dyn Inode>,
|
||||||
|
remove_dir: bool,
|
||||||
|
task: Arc<Task>,
|
||||||
|
) -> Result<()> {
|
||||||
// First, resolve the target inode so we can inspect its type.
|
// First, resolve the target inode so we can inspect its type.
|
||||||
let target_inode = self.resolve_path(path, root.clone()).await?;
|
let target_inode = self.resolve_path(path, root.clone(), task.clone()).await?;
|
||||||
|
|
||||||
let attr = target_inode.getattr().await?;
|
let attr = target_inode.getattr().await?;
|
||||||
|
|
||||||
@@ -382,7 +436,7 @@ impl VFS {
|
|||||||
|
|
||||||
// Determine the parent directory inode in which to perform the unlink.
|
// Determine the parent directory inode in which to perform the unlink.
|
||||||
let parent_inode = if let Some(parent_path) = path.parent() {
|
let parent_inode = if let Some(parent_path) = path.parent() {
|
||||||
self.resolve_path(parent_path, root.clone()).await?
|
self.resolve_path(parent_path, root.clone(), task).await?
|
||||||
} else {
|
} else {
|
||||||
root.clone()
|
root.clone()
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -14,10 +14,11 @@ pub async fn sys_faccessat(dirfd: Fd, path: TUA<c_char>, mode: i32) -> Result<us
|
|||||||
pub async fn sys_faccessat2(dirfd: Fd, path: TUA<c_char>, mode: i32, flags: i32) -> Result<usize> {
|
pub async fn sys_faccessat2(dirfd: Fd, path: TUA<c_char>, mode: i32, flags: i32) -> Result<usize> {
|
||||||
let mut buf = [0; 1024];
|
let mut buf = [0; 1024];
|
||||||
|
|
||||||
|
let task = current_task();
|
||||||
let access_mode = AccessMode::from_bits_retain(mode);
|
let access_mode = AccessMode::from_bits_retain(mode);
|
||||||
let path = Path::new(UserCStr::from_ptr(path).copy_from_user(&mut buf).await?);
|
let path = Path::new(UserCStr::from_ptr(path).copy_from_user(&mut buf).await?);
|
||||||
let start_node = resolve_at_start_node(dirfd, path).await?;
|
let start_node = resolve_at_start_node(dirfd, path).await?;
|
||||||
let node = VFS.resolve_path(path, start_node).await?;
|
let node = VFS.resolve_path(path, start_node, task.clone()).await?;
|
||||||
let at_flags = AtFlags::from_bits_retain(flags);
|
let at_flags = AtFlags::from_bits_retain(flags);
|
||||||
|
|
||||||
// If mode is F_OK (value 0), the check is for the file's existence.
|
// If mode is F_OK (value 0), the check is for the file's existence.
|
||||||
@@ -26,7 +27,6 @@ pub async fn sys_faccessat2(dirfd: Fd, path: TUA<c_char>, mode: i32, flags: i32)
|
|||||||
return Ok(0);
|
return Ok(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
let task = current_task();
|
|
||||||
let attrs = node.getattr().await?;
|
let attrs = node.getattr().await?;
|
||||||
let creds = task.creds.lock_save_irq();
|
let creds = task.creds.lock_save_irq();
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
use crate::current_task;
|
||||||
use crate::fs::VFS;
|
use crate::fs::VFS;
|
||||||
use crate::fs::syscalls::at::resolve_at_start_node;
|
use crate::fs::syscalls::at::resolve_at_start_node;
|
||||||
use crate::memory::uaccess::cstr::UserCStr;
|
use crate::memory::uaccess::cstr::UserCStr;
|
||||||
@@ -14,10 +15,11 @@ pub async fn sys_mkdirat(
|
|||||||
) -> libkernel::error::Result<usize> {
|
) -> libkernel::error::Result<usize> {
|
||||||
let mut buf = [0; 1024];
|
let mut buf = [0; 1024];
|
||||||
|
|
||||||
|
let task = current_task();
|
||||||
let path = Path::new(UserCStr::from_ptr(path).copy_from_user(&mut buf).await?);
|
let path = Path::new(UserCStr::from_ptr(path).copy_from_user(&mut buf).await?);
|
||||||
let start_node = resolve_at_start_node(dirfd, path).await?;
|
let start_node = resolve_at_start_node(dirfd, path).await?;
|
||||||
let mode = FilePermissions::from_bits_retain(mode);
|
let mode = FilePermissions::from_bits_retain(mode);
|
||||||
|
|
||||||
VFS.mkdir(path, start_node, mode).await?;
|
VFS.mkdir(path, start_node, mode, task.clone()).await?;
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,14 +11,17 @@ use super::resolve_at_start_node;
|
|||||||
pub async fn sys_openat(dirfd: Fd, path: TUA<c_char>, flags: u32, mode: u16) -> Result<usize> {
|
pub async fn sys_openat(dirfd: Fd, path: TUA<c_char>, flags: u32, mode: u16) -> Result<usize> {
|
||||||
let mut buf = [0; 1024];
|
let mut buf = [0; 1024];
|
||||||
|
|
||||||
|
let task = current_task();
|
||||||
let flags = OpenFlags::from_bits_truncate(flags);
|
let flags = OpenFlags::from_bits_truncate(flags);
|
||||||
let path = Path::new(UserCStr::from_ptr(path).copy_from_user(&mut buf).await?);
|
let path = Path::new(UserCStr::from_ptr(path).copy_from_user(&mut buf).await?);
|
||||||
let start_node = resolve_at_start_node(dirfd, path).await?;
|
let start_node = resolve_at_start_node(dirfd, path).await?;
|
||||||
let mode = FilePermissions::from_bits_retain(mode);
|
let mode = FilePermissions::from_bits_retain(mode);
|
||||||
|
|
||||||
let file = VFS.open(path, flags, start_node, mode).await?;
|
let file = VFS
|
||||||
|
.open(path, flags, start_node, mode, task.clone())
|
||||||
|
.await?;
|
||||||
|
|
||||||
let fd = current_task().fd_table.lock_save_irq().insert(file)?;
|
let fd = task.fd_table.lock_save_irq().insert(file)?;
|
||||||
|
|
||||||
Ok(fd.as_raw() as _)
|
Ok(fd.as_raw() as _)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
|
current_task,
|
||||||
fs::{VFS, syscalls::at::resolve_at_start_node},
|
fs::{VFS, syscalls::at::resolve_at_start_node},
|
||||||
memory::uaccess::{UserCopyable, copy_to_user, cstr::UserCStr},
|
memory::uaccess::{UserCopyable, copy_to_user, cstr::UserCStr},
|
||||||
process::fd_table::Fd,
|
process::fd_table::Fd,
|
||||||
@@ -84,11 +85,12 @@ pub async fn sys_newfstatat(
|
|||||||
) -> Result<usize> {
|
) -> Result<usize> {
|
||||||
let mut buf = [0; 1024];
|
let mut buf = [0; 1024];
|
||||||
|
|
||||||
|
let task = current_task();
|
||||||
let _flags = AtFlags::from_bits_truncate(flags);
|
let _flags = AtFlags::from_bits_truncate(flags);
|
||||||
let path = Path::new(UserCStr::from_ptr(path).copy_from_user(&mut buf).await?);
|
let path = Path::new(UserCStr::from_ptr(path).copy_from_user(&mut buf).await?);
|
||||||
|
|
||||||
let start_node = resolve_at_start_node(dirfd, path).await?;
|
let start_node = resolve_at_start_node(dirfd, path).await?;
|
||||||
let node = VFS.resolve_path(path, start_node).await?;
|
let node = VFS.resolve_path(path, start_node, task.clone()).await?;
|
||||||
|
|
||||||
let attr = node.getattr().await?;
|
let attr = node.getattr().await?;
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ use core::ffi::c_char;
|
|||||||
use libkernel::{error::Result, fs::path::Path, memory::address::TUA};
|
use libkernel::{error::Result, fs::path::Path, memory::address::TUA};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
current_task,
|
||||||
fs::{VFS, syscalls::at::resolve_at_start_node},
|
fs::{VFS, syscalls::at::resolve_at_start_node},
|
||||||
memory::uaccess::cstr::UserCStr,
|
memory::uaccess::cstr::UserCStr,
|
||||||
process::fd_table::Fd,
|
process::fd_table::Fd,
|
||||||
@@ -21,12 +22,15 @@ pub async fn sys_unlinkat(dirfd: Fd, path: TUA<c_char>, flags: u32) -> Result<us
|
|||||||
let mut buf = [0u8; 1024];
|
let mut buf = [0u8; 1024];
|
||||||
let path = Path::new(UserCStr::from_ptr(path).copy_from_user(&mut buf).await?);
|
let path = Path::new(UserCStr::from_ptr(path).copy_from_user(&mut buf).await?);
|
||||||
|
|
||||||
|
let task = current_task();
|
||||||
|
|
||||||
// Determine the starting inode for path resolution.
|
// Determine the starting inode for path resolution.
|
||||||
let start_node = resolve_at_start_node(dirfd, path).await?;
|
let start_node = resolve_at_start_node(dirfd, path).await?;
|
||||||
|
|
||||||
let remove_dir = flags & AT_REMOVEDIR != 0;
|
let remove_dir = flags & AT_REMOVEDIR != 0;
|
||||||
|
|
||||||
VFS.unlink(path, start_node, remove_dir).await?;
|
VFS.unlink(path, start_node, remove_dir, task.clone())
|
||||||
|
.await?;
|
||||||
|
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,9 +34,24 @@ pub async fn sys_chdir(path: TUA<c_char>) -> Result<usize> {
|
|||||||
let current_path = task.cwd.lock_save_irq().0.clone();
|
let current_path = task.cwd.lock_save_irq().0.clone();
|
||||||
let new_path = task.cwd.lock_save_irq().1.join(path);
|
let new_path = task.cwd.lock_save_irq().1.join(path);
|
||||||
|
|
||||||
let node = VFS.resolve_path(path, current_path).await?;
|
let node = VFS.resolve_path(path, current_path, task.clone()).await?;
|
||||||
|
|
||||||
*task.cwd.lock_save_irq() = (node, new_path);
|
*task.cwd.lock_save_irq() = (node, new_path);
|
||||||
|
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn sys_chroot(path: TUA<c_char>) -> Result<usize> {
|
||||||
|
let mut buf = [0; 1024];
|
||||||
|
|
||||||
|
let path = Path::new(UserCStr::from_ptr(path).copy_from_user(&mut buf).await?);
|
||||||
|
let task = current_task();
|
||||||
|
let current_path = task.root.lock_save_irq().0.clone();
|
||||||
|
let new_path = task.root.lock_save_irq().1.join(path);
|
||||||
|
|
||||||
|
let node = VFS.resolve_path(path, current_path, task.clone()).await?;
|
||||||
|
|
||||||
|
*task.root.lock_save_irq() = (node, new_path);
|
||||||
|
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ async fn launch_init(opts: KOptions) {
|
|||||||
// Process all automounts.
|
// Process all automounts.
|
||||||
for (path, fs) in opts.automounts.iter() {
|
for (path, fs) in opts.automounts.iter() {
|
||||||
let mount_point = VFS
|
let mount_point = VFS
|
||||||
.resolve_path(path, VFS.root_inode())
|
.resolve_path_absolute(path, VFS.root_inode())
|
||||||
.await
|
.await
|
||||||
.unwrap_or_else(|e| panic!("Could not find automount path: {}. {e}", path.as_str()));
|
.unwrap_or_else(|e| panic!("Could not find automount path: {}. {e}", path.as_str()));
|
||||||
|
|
||||||
@@ -117,7 +117,7 @@ async fn launch_init(opts: KOptions) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let inode = VFS
|
let inode = VFS
|
||||||
.resolve_path(&init, VFS.root_inode())
|
.resolve_path_absolute(&init, VFS.root_inode())
|
||||||
.await
|
.await
|
||||||
.expect("Unable to find init");
|
.expect("Unable to find init");
|
||||||
|
|
||||||
@@ -127,8 +127,9 @@ async fn launch_init(opts: KOptions) {
|
|||||||
assert!(task.process.tgid.is_init());
|
assert!(task.process.tgid.is_init());
|
||||||
|
|
||||||
// Now that the root fs has been mounted, set the real root inode as the
|
// Now that the root fs has been mounted, set the real root inode as the
|
||||||
// cwd.
|
// cwd and root.
|
||||||
*task.cwd.lock_save_irq() = (VFS.root_inode(), PathBuf::new());
|
*task.cwd.lock_save_irq() = (VFS.root_inode(), PathBuf::new());
|
||||||
|
*task.root.lock_save_irq() = (VFS.root_inode(), PathBuf::new());
|
||||||
|
|
||||||
let console = VFS
|
let console = VFS
|
||||||
.open(
|
.open(
|
||||||
@@ -136,6 +137,7 @@ async fn launch_init(opts: KOptions) {
|
|||||||
OpenFlags::O_RDWR,
|
OpenFlags::O_RDWR,
|
||||||
VFS.root_inode(),
|
VFS.root_inode(),
|
||||||
FilePermissions::empty(),
|
FilePermissions::empty(),
|
||||||
|
task.clone(),
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.expect("Could not open console for init process");
|
.expect("Could not open console for init process");
|
||||||
|
|||||||
@@ -105,6 +105,12 @@ pub async fn sys_clone(
|
|||||||
Arc::new(SpinLock::new(current_task.cwd.lock_save_irq().clone()))
|
Arc::new(SpinLock::new(current_task.cwd.lock_save_irq().clone()))
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let root = if flags.contains(CloneFlags::CLONE_FS) {
|
||||||
|
current_task.root.clone()
|
||||||
|
} else {
|
||||||
|
Arc::new(SpinLock::new(current_task.root.lock_save_irq().clone()))
|
||||||
|
};
|
||||||
|
|
||||||
let creds = current_task.creds.lock_save_irq().clone();
|
let creds = current_task.creds.lock_save_irq().clone();
|
||||||
|
|
||||||
let mut user_ctx = *current_task.ctx.lock_save_irq().user();
|
let mut user_ctx = *current_task.ctx.lock_save_irq().user();
|
||||||
@@ -120,6 +126,7 @@ pub async fn sys_clone(
|
|||||||
vm,
|
vm,
|
||||||
fd_table: files,
|
fd_table: files,
|
||||||
cwd,
|
cwd,
|
||||||
|
root,
|
||||||
creds: SpinLock::new(creds),
|
creds: SpinLock::new(creds),
|
||||||
ctx: SpinLock::new(Context::from_user_ctx(user_ctx)),
|
ctx: SpinLock::new(Context::from_user_ctx(user_ctx)),
|
||||||
priority: current_task.priority,
|
priority: current_task.priority,
|
||||||
|
|||||||
@@ -276,8 +276,11 @@ pub async fn sys_execve(
|
|||||||
usr_env = usr_env.add_objs(1);
|
usr_env = usr_env.add_objs(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let task = current_task();
|
||||||
let path = Path::new(UserCStr::from_ptr(path).copy_from_user(&mut buf).await?);
|
let path = Path::new(UserCStr::from_ptr(path).copy_from_user(&mut buf).await?);
|
||||||
let inode = VFS.resolve_path(path, VFS.root_inode()).await?;
|
let inode = VFS
|
||||||
|
.resolve_path(path, VFS.root_inode(), task.clone())
|
||||||
|
.await?;
|
||||||
|
|
||||||
kernel_exec(inode, argv, envp).await?;
|
kernel_exec(inode, argv, envp).await?;
|
||||||
|
|
||||||
|
|||||||
@@ -168,6 +168,7 @@ pub struct Task {
|
|||||||
pub process: Arc<ThreadGroup>,
|
pub process: Arc<ThreadGroup>,
|
||||||
pub vm: Arc<SpinLock<ProcVM>>,
|
pub vm: Arc<SpinLock<ProcVM>>,
|
||||||
pub cwd: Arc<SpinLock<(Arc<dyn Inode>, PathBuf)>>,
|
pub cwd: Arc<SpinLock<(Arc<dyn Inode>, PathBuf)>>,
|
||||||
|
pub root: Arc<SpinLock<(Arc<dyn Inode>, PathBuf)>>,
|
||||||
pub creds: SpinLock<Credentials>,
|
pub creds: SpinLock<Credentials>,
|
||||||
pub fd_table: Arc<SpinLock<FileDescriptorTable>>,
|
pub fd_table: Arc<SpinLock<FileDescriptorTable>>,
|
||||||
pub ctx: SpinLock<Context>,
|
pub ctx: SpinLock<Context>,
|
||||||
@@ -201,6 +202,7 @@ impl Task {
|
|||||||
state: Arc::new(SpinLock::new(TaskState::Runnable)),
|
state: Arc::new(SpinLock::new(TaskState::Runnable)),
|
||||||
priority: i8::MIN,
|
priority: i8::MIN,
|
||||||
cwd: Arc::new(SpinLock::new((Arc::new(DummyInode {}), PathBuf::new()))),
|
cwd: Arc::new(SpinLock::new((Arc::new(DummyInode {}), PathBuf::new()))),
|
||||||
|
root: Arc::new(SpinLock::new((Arc::new(DummyInode {}), PathBuf::new()))),
|
||||||
creds: SpinLock::new(Credentials::new_root()),
|
creds: SpinLock::new(Credentials::new_root()),
|
||||||
ctx: SpinLock::new(Context::from_user_ctx(user_ctx)),
|
ctx: SpinLock::new(Context::from_user_ctx(user_ctx)),
|
||||||
vm: Arc::new(SpinLock::new(vm)),
|
vm: Arc::new(SpinLock::new(vm)),
|
||||||
@@ -222,6 +224,7 @@ impl Task {
|
|||||||
process: ThreadGroupBuilder::new(Tgid::init()).build(),
|
process: ThreadGroupBuilder::new(Tgid::init()).build(),
|
||||||
state: Arc::new(SpinLock::new(TaskState::Runnable)),
|
state: Arc::new(SpinLock::new(TaskState::Runnable)),
|
||||||
cwd: Arc::new(SpinLock::new((Arc::new(DummyInode {}), PathBuf::new()))),
|
cwd: Arc::new(SpinLock::new((Arc::new(DummyInode {}), PathBuf::new()))),
|
||||||
|
root: Arc::new(SpinLock::new((Arc::new(DummyInode {}), PathBuf::new()))),
|
||||||
creds: SpinLock::new(Credentials::new_root()),
|
creds: SpinLock::new(Credentials::new_root()),
|
||||||
vm: Arc::new(SpinLock::new(
|
vm: Arc::new(SpinLock::new(
|
||||||
ProcessVM::empty().expect("Could not create init process's VM"),
|
ProcessVM::empty().expect("Could not create init process's VM"),
|
||||||
|
|||||||
@@ -54,6 +54,24 @@ fn test_chdir() {
|
|||||||
println!(" OK");
|
println!(" OK");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn test_chroot() {
|
||||||
|
print!("Testing chroot syscall ...");
|
||||||
|
let file = "/bin/busybox";
|
||||||
|
let c_file = std::ffi::CString::new(file).unwrap();
|
||||||
|
let path = std::ffi::CString::new("/dev").unwrap();
|
||||||
|
unsafe {
|
||||||
|
if libc::chroot(path.as_ptr()) != 0 {
|
||||||
|
panic!("chroot failed");
|
||||||
|
} else {
|
||||||
|
let fd = libc::open(c_file.as_ptr(), libc::O_RDONLY);
|
||||||
|
if fd != -1 {
|
||||||
|
panic!("chroot failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
println!(" OK");
|
||||||
|
}
|
||||||
|
|
||||||
fn test_fork() {
|
fn test_fork() {
|
||||||
print!("Testing fork syscall ...");
|
print!("Testing fork syscall ...");
|
||||||
unsafe {
|
unsafe {
|
||||||
@@ -173,6 +191,7 @@ fn main() {
|
|||||||
run_test(test_opendir);
|
run_test(test_opendir);
|
||||||
run_test(test_readdir);
|
run_test(test_readdir);
|
||||||
run_test(test_chdir);
|
run_test(test_chdir);
|
||||||
|
run_test(test_chroot);
|
||||||
run_test(test_fork);
|
run_test(test_fork);
|
||||||
run_test(test_read);
|
run_test(test_read);
|
||||||
run_test(test_write);
|
run_test(test_write);
|
||||||
|
|||||||
Reference in New Issue
Block a user